mutt stable branch with some hacks
at master 4960 lines 129 kB view raw
1/* crypt-gpgme.c - GPGME based crypto operations 2 * Copyright (C) 1996-1997,2007 Michael R. Elkins <me@cs.hmc.edu> 3 * Copyright (C) 1998-2000 Thomas Roessler <roessler@does-not-exist.org> 4 * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org> 5 * Oliver Ehli <elmy@acm.org> 6 * Copyright (C) 2002-2004 g10 Code GmbH 7 * Copyright (C) 2010,2012-2013 Michael R. Elkins <me@sigpipe.org> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 */ 23 24#if HAVE_CONFIG_H 25# include "config.h" 26#endif 27 28#ifdef CRYPT_BACKEND_GPGME 29 30#include "mutt.h" 31#include "mutt_crypt.h" 32#include "mutt_menu.h" 33#include "mutt_curses.h" 34#include "mime.h" 35#include "copy.h" 36#include "pager.h" 37#include "sort.h" 38 39#include <sys/wait.h> 40#include <string.h> 41#include <stdlib.h> 42#include <unistd.h> 43#include <sys/stat.h> 44#include <errno.h> 45#include <ctype.h> 46 47#include <gpgme.h> 48 49#ifdef HAVE_LOCALE_H 50#include <locale.h> 51#endif 52#ifdef HAVE_LANGINFO_D_T_FMT 53#include <langinfo.h> 54#endif 55 56#ifdef HAVE_SYS_TIME_H 57# include <sys/time.h> 58#endif 59 60#ifdef HAVE_SYS_RESOURCE_H 61# include <sys/resource.h> 62#endif 63 64/* 65 * Helper macros. 66 */ 67#define digitp(p) (*(p) >= '0' && *(p) <= '9') 68#define hexdigitp(a) (digitp (a) \ 69 || (*(a) >= 'A' && *(a) <= 'F') \ 70 || (*(a) >= 'a' && *(a) <= 'f')) 71#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ 72 *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) 73#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) 74 75#define PKA_NOTATION_NAME "pka-address@gnupg.org" 76#define is_pka_notation(notation) ((notation)->name && \ 77 ! strcmp ((notation)->name, \ 78 PKA_NOTATION_NAME)) 79 80/* Values used for comparing addresses. */ 81#define CRYPT_KV_VALID 1 82#define CRYPT_KV_ADDR 2 83#define CRYPT_KV_STRING 4 84#define CRYPT_KV_STRONGID 8 85#define CRYPT_KV_MATCH (CRYPT_KV_ADDR|CRYPT_KV_STRING) 86 87/* 88 * Type definitions. 89 */ 90 91struct crypt_cache 92{ 93 char *what; 94 char *dflt; 95 struct crypt_cache *next; 96}; 97 98struct dn_array_s 99{ 100 char *key; 101 char *value; 102}; 103 104/* We work based on user IDs, getting from a user ID to the key is 105 check and does not need any memory (gpgme uses reference counting). */ 106typedef struct crypt_keyinfo 107{ 108 struct crypt_keyinfo *next; 109 gpgme_key_t kobj; 110 int idx; /* and the user ID at this index */ 111 const char *uid; /* and for convenience point to this user ID */ 112 unsigned int flags; /* global and per uid flags (for convenience)*/ 113 gpgme_validity_t validity; /* uid validity (cached for convenience) */ 114} crypt_key_t; 115 116typedef struct crypt_entry 117{ 118 size_t num; 119 crypt_key_t *key; 120} crypt_entry_t; 121 122 123static struct crypt_cache *id_defaults = NULL; 124static gpgme_key_t signature_key = NULL; 125static char *current_sender = NULL; 126 127 128/* 129 * General helper functions. 130 */ 131 132/* return true when s points to a digit or letter. */ 133static int 134digit_or_letter (const unsigned char *s) 135{ 136 return ( (*s >= '0' && *s < '9') 137 || (*s >= 'A' && *s <= 'Z') 138 || (*s >= 'a' && *s <= 'z')); 139} 140 141 142/* Print the utf-8 encoded string BUF of length LEN bytes to stream 143 FP. Convert the character set. */ 144static void 145print_utf8 (FILE *fp, const char *buf, size_t len) 146{ 147 char *tstr; 148 149 tstr = safe_malloc (len+1); 150 memcpy (tstr, buf, len); 151 tstr[len] = 0; 152 153 /* fromcode "utf-8" is sure, so we don't want 154 * charset-hook corrections: flags must be 0. 155 */ 156 mutt_convert_string (&tstr, "utf-8", Charset, 0); 157 fputs (tstr, fp); 158 FREE (&tstr); 159} 160 161 162/* 163 * Key management. 164 */ 165 166/* Return the keyID for the key K. Note that this string is valid as 167 long as K is valid */ 168static const char *crypt_keyid (crypt_key_t *k) 169{ 170 const char *s = "????????"; 171 172 if (k->kobj && k->kobj->subkeys) 173 { 174 s = k->kobj->subkeys->keyid; 175 if ((! option (OPTPGPLONGIDS)) && (strlen (s) == 16)) 176 /* Return only the short keyID. */ 177 s += 8; 178 } 179 180 return s; 181} 182 183/* Return the long keyID for the key K. */ 184static const char *crypt_long_keyid (crypt_key_t *k) 185{ 186 const char *s = "????????????????"; 187 188 if (k->kobj && k->kobj->subkeys) 189 { 190 s = k->kobj->subkeys->keyid; 191 } 192 193 return s; 194} 195 196/* Return the short keyID for the key K. */ 197static const char *crypt_short_keyid (crypt_key_t *k) 198{ 199 const char *s = "????????"; 200 201 if (k->kobj && k->kobj->subkeys) 202 { 203 s = k->kobj->subkeys->keyid; 204 if (strlen (s) == 16) 205 s += 8; 206 } 207 208 return s; 209} 210 211/* Return the hexstring fingerprint from the key K. */ 212static const char *crypt_fpr (crypt_key_t *k) 213{ 214 const char *s = ""; 215 216 if (k->kobj && k->kobj->subkeys) 217 s = k->kobj->subkeys->fpr; 218 219 return s; 220} 221 222/* Returns the fingerprint if available, otherwise 223 * returns the long keyid. 224 */ 225static const char *crypt_fpr_or_lkeyid(crypt_key_t *k) 226{ 227 const char *s = "????????????????"; 228 229 if (k->kobj && k->kobj->subkeys) 230 { 231 if (k->kobj->subkeys->fpr) 232 s = k->kobj->subkeys->fpr; 233 else 234 s = k->kobj->subkeys->keyid; 235 } 236 237 return s; 238} 239 240/* Parse FLAGS and return a statically allocated(!) string with them. */ 241static char *crypt_key_abilities (int flags) 242{ 243 static char buff[3]; 244 245 if (!(flags & KEYFLAG_CANENCRYPT)) 246 buff[0] = '-'; 247 else if (flags & KEYFLAG_PREFER_SIGNING) 248 buff[0] = '.'; 249 else 250 buff[0] = 'e'; 251 252 if (!(flags & KEYFLAG_CANSIGN)) 253 buff[1] = '-'; 254 else if (flags & KEYFLAG_PREFER_ENCRYPTION) 255 buff[1] = '.'; 256 else 257 buff[1] = 's'; 258 259 buff[2] = '\0'; 260 261 return buff; 262} 263 264/* Parse FLAGS and return a character describing the most important flag. */ 265static char crypt_flags (int flags) 266{ 267 if (flags & KEYFLAG_REVOKED) 268 return 'R'; 269 else if (flags & KEYFLAG_EXPIRED) 270 return 'X'; 271 else if (flags & KEYFLAG_DISABLED) 272 return 'd'; 273 else if (flags & KEYFLAG_CRITICAL) 274 return 'c'; 275 else 276 return ' '; 277} 278 279/* Return a copy of KEY. */ 280static crypt_key_t *crypt_copy_key (crypt_key_t *key) 281{ 282 crypt_key_t *k; 283 284 k = safe_calloc (1, sizeof *k); 285 k->kobj = key->kobj; 286 gpgme_key_ref (key->kobj); 287 k->idx = key->idx; 288 k->uid = key->uid; 289 k->flags = key->flags; 290 k->validity = key->validity; 291 292 return k; 293} 294 295/* Release all the keys at the address of KEYLIST and set the address 296 to NULL. */ 297static void crypt_free_key (crypt_key_t **keylist) 298{ 299 crypt_key_t *k; 300 301 if (!keylist) 302 return; 303 304 while (*keylist) 305 { 306 k = *keylist; 307 *keylist = (*keylist)->next; 308 309 gpgme_key_unref (k->kobj); 310 FREE (&k); 311 } 312} 313 314/* Return trute when key K is valid. */ 315static int crypt_key_is_valid (crypt_key_t *k) 316{ 317 if (k->flags & KEYFLAG_CANTUSE) 318 return 0; 319 return 1; 320} 321 322/* Return true whe validity of KEY is sufficient. */ 323static int crypt_id_is_strong (crypt_key_t *key) 324{ 325 unsigned int is_strong = 0; 326 327 if ((key->flags & KEYFLAG_ISX509)) 328 return 1; 329 330 switch (key->validity) 331 { 332 case GPGME_VALIDITY_UNKNOWN: 333 case GPGME_VALIDITY_UNDEFINED: 334 case GPGME_VALIDITY_NEVER: 335 case GPGME_VALIDITY_MARGINAL: 336 is_strong = 0; 337 break; 338 339 case GPGME_VALIDITY_FULL: 340 case GPGME_VALIDITY_ULTIMATE: 341 is_strong = 1; 342 break; 343 } 344 345 return is_strong; 346} 347 348/* Return true when the KEY is valid, i.e. not marked as unusable. */ 349static int crypt_id_is_valid (crypt_key_t *key) 350{ 351 return ! (key->flags & KEYFLAG_CANTUSE); 352} 353 354/* Return a bit vector describing how well the addresses ADDR and 355 U_ADDR match and whether KEY is valid. */ 356static int crypt_id_matches_addr (ADDRESS *addr, ADDRESS *u_addr, 357 crypt_key_t *key) 358{ 359 int rv = 0; 360 361 if (crypt_id_is_valid (key)) 362 rv |= CRYPT_KV_VALID; 363 364 if (crypt_id_is_strong (key)) 365 rv |= CRYPT_KV_STRONGID; 366 367 if (addr->mailbox && u_addr->mailbox 368 && mutt_strcasecmp (addr->mailbox, u_addr->mailbox) == 0) 369 rv |= CRYPT_KV_ADDR; 370 371 if (addr->personal && u_addr->personal 372 && mutt_strcasecmp (addr->personal, u_addr->personal) == 0) 373 rv |= CRYPT_KV_STRING; 374 375 return rv; 376} 377 378 379/* 380 * GPGME convenient functions. 381 */ 382 383/* Create a new gpgme context and return it. With FOR_SMIME set to 384 true, the protocol of the context is set to CMS. */ 385static gpgme_ctx_t create_gpgme_context (int for_smime) 386{ 387 gpgme_error_t err; 388 gpgme_ctx_t ctx; 389 390 err = gpgme_new (&ctx); 391 if (err) 392 { 393 mutt_error (_("error creating gpgme context: %s\n"), gpgme_strerror (err)); 394 sleep (2); 395 mutt_exit (1); 396 } 397 398 if (for_smime) 399 { 400 err = gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); 401 if (err) 402 { 403 mutt_error (_("error enabling CMS protocol: %s\n"), 404 gpgme_strerror (err)); 405 sleep (2); 406 mutt_exit (1); 407 } 408 } 409 410 return ctx; 411} 412 413/* Create a new gpgme data object. This is a wrapper to die on 414 error. */ 415static gpgme_data_t create_gpgme_data (void) 416{ 417 gpgme_error_t err; 418 gpgme_data_t data; 419 420 err = gpgme_data_new (&data); 421 if (err) 422 { 423 mutt_error (_("error creating gpgme data object: %s\n"), 424 gpgme_strerror (err)); 425 sleep (2); 426 mutt_exit (1); 427 } 428 return data; 429} 430 431/* Create a new GPGME Data object from the mail body A. With CONVERT 432 passed as true, the lines are converted to CR,LF if required. 433 Return NULL on error or the gpgme_data_t object on success. */ 434static gpgme_data_t body_to_data_object (BODY *a, int convert) 435{ 436 char tempfile[_POSIX_PATH_MAX]; 437 FILE *fptmp; 438 int err = 0; 439 gpgme_data_t data; 440 441 mutt_mktemp (tempfile, sizeof (tempfile)); 442 fptmp = safe_fopen (tempfile, "w+"); 443 if (!fptmp) 444 { 445 mutt_perror (tempfile); 446 return NULL; 447 } 448 449 mutt_write_mime_header (a, fptmp); 450 fputc ('\n', fptmp); 451 mutt_write_mime_body (a, fptmp); 452 453 if (convert) 454 { 455 int c, hadcr = 0; 456 unsigned char buf[1]; 457 458 data = create_gpgme_data (); 459 rewind (fptmp); 460 while ((c = fgetc (fptmp)) != EOF) 461 { 462 if (c == '\r') 463 hadcr = 1; 464 else 465 { 466 if (c == '\n' && !hadcr) 467 { 468 buf[0] = '\r'; 469 gpgme_data_write (data, buf, 1); 470 } 471 472 hadcr = 0; 473 } 474 /* FIXME: This is quite suboptimal */ 475 buf[0] = c; 476 gpgme_data_write (data, buf, 1); 477 } 478 safe_fclose (&fptmp); 479 gpgme_data_seek (data, 0, SEEK_SET); 480 } 481 else 482 { 483 safe_fclose (&fptmp); 484 err = gpgme_data_new_from_file (&data, tempfile, 1); 485 } 486 unlink (tempfile); 487 if (err) 488 { 489 mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err)); 490 return NULL; 491 } 492 493 return data; 494} 495 496/* Create a GPGME data object from the stream FP but limit the object 497 to LENGTH bytes starting at OFFSET bytes from the beginning of the 498 file. */ 499static gpgme_data_t file_to_data_object (FILE *fp, long offset, long length) 500{ 501 int err = 0; 502 gpgme_data_t data; 503 504 err = gpgme_data_new_from_filepart (&data, NULL, fp, offset, length); 505 if (err) 506 { 507 mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err)); 508 return NULL; 509 } 510 511 return data; 512} 513 514/* Write a GPGME data object to the stream FP. */ 515static int data_object_to_stream (gpgme_data_t data, FILE *fp) 516{ 517 int err; 518 char buf[4096], *p; 519 ssize_t nread; 520 521 err = ((gpgme_data_seek (data, 0, SEEK_SET) == -1) 522 ? gpgme_error_from_errno (errno) : 0); 523 if (err) 524 { 525 mutt_error (_("error rewinding data object: %s\n"), gpgme_strerror (err)); 526 return -1; 527 } 528 529 while ((nread = gpgme_data_read (data, buf, sizeof (buf)))) 530 { 531 /* fixme: we are not really converting CRLF to LF but just 532 skipping CR. Doing it correctly needs a more complex logic */ 533 for (p=buf; nread; p++, nread--) 534 { 535 if (*p != '\r') 536 putc (*p, fp); 537 } 538 539 if (ferror (fp)) 540 { 541 mutt_perror ("[tempfile]"); 542 return -1; 543 } 544 } 545 if (nread == -1) 546 { 547 mutt_error (_("error reading data object: %s\n"), strerror (errno)); 548 return -1; 549 } 550 return 0; 551} 552 553/* Copy a data object to a temporary file. 554 * The tempfile name may be optionally passed in. 555 * If ret_fp is passed in, the file will be rewound, left open, and returned 556 * via that parameter. 557 * The tempfile name is returned, and must be freed. 558 */ 559static char *data_object_to_tempfile (gpgme_data_t data, char *tempf, FILE **ret_fp) 560{ 561 int err; 562 char tempfb[_POSIX_PATH_MAX]; 563 FILE *fp; 564 size_t nread = 0; 565 566 if (!tempf) 567 { 568 mutt_mktemp (tempfb, sizeof (tempfb)); 569 tempf = tempfb; 570 } 571 if ((fp = safe_fopen (tempf, tempf == tempfb ? "w+" : "a+")) == NULL) 572 { 573 mutt_perror _("Can't create temporary file"); 574 return NULL; 575 } 576 577 err = ((gpgme_data_seek (data, 0, SEEK_SET) == -1) 578 ? gpgme_error_from_errno (errno) : 0); 579 if (!err) 580 { 581 char buf[4096]; 582 583 while ((nread = gpgme_data_read (data, buf, sizeof (buf)))) 584 { 585 if (fwrite (buf, nread, 1, fp) != 1) 586 { 587 mutt_perror (tempf); 588 safe_fclose (&fp); 589 unlink (tempf); 590 return NULL; 591 } 592 } 593 } 594 if (ret_fp) 595 rewind (fp); 596 else 597 safe_fclose (&fp); 598 if (nread == -1) 599 { 600 mutt_error (_("error reading data object: %s\n"), gpgme_strerror (err)); 601 unlink (tempf); 602 safe_fclose (&fp); 603 return NULL; 604 } 605 if (ret_fp) 606 *ret_fp = fp; 607 return safe_strdup (tempf); 608} 609 610 611static void free_recipient_set (gpgme_key_t **p_rset) 612{ 613 gpgme_key_t *rset, k; 614 615 if (!p_rset) 616 return; 617 618 rset = *p_rset; 619 if (!rset) 620 return; 621 622 while (*rset) 623 { 624 k = *rset; 625 gpgme_key_unref (k); 626 rset++; 627 } 628 629 FREE (p_rset); /* __FREE_CHECKED__ */ 630} 631 632 633/* Create a GpgmeRecipientSet from the keys in the string KEYLIST. 634 The keys must be space delimited. */ 635static gpgme_key_t *create_recipient_set (const char *keylist, 636 gpgme_protocol_t protocol) 637{ 638 int err; 639 const char *s; 640 char buf[100]; 641 int i; 642 gpgme_key_t *rset = NULL; 643 unsigned int rset_n = 0; 644 gpgme_key_t key = NULL; 645 gpgme_ctx_t context = NULL; 646 647 err = gpgme_new (&context); 648 if (! err) 649 err = gpgme_set_protocol (context, protocol); 650 651 if (! err) 652 { 653 s = keylist; 654 do { 655 while (*s == ' ') 656 s++; 657 for (i=0; *s && *s != ' ' && i < sizeof(buf)-1;) 658 buf[i++] = *s++; 659 buf[i] = 0; 660 if (*buf) 661 { 662 if (i>1 && buf[i-1] == '!') 663 { 664 /* The user selected to override the validity of that 665 key. */ 666 buf[i-1] = 0; 667 668 err = gpgme_get_key (context, buf, &key, 0); 669 if (! err) 670 key->uids->validity = GPGME_VALIDITY_FULL; 671 buf[i-1] = '!'; 672 } 673 else 674 err = gpgme_get_key (context, buf, &key, 0); 675 676 safe_realloc (&rset, sizeof (*rset) * (rset_n + 1)); 677 if (! err) 678 rset[rset_n++] = key; 679 else 680 { 681 mutt_error (_("error adding recipient `%s': %s\n"), 682 buf, gpgme_strerror (err)); 683 rset[rset_n] = NULL; 684 free_recipient_set (&rset); 685 gpgme_release (context); 686 return NULL; 687 } 688 } 689 } while (*s); 690 } 691 692 /* NULL terminate. */ 693 safe_realloc (&rset, sizeof (*rset) * (rset_n + 1)); 694 rset[rset_n++] = NULL; 695 696 if (context) 697 gpgme_release (context); 698 699 return rset; 700} 701 702 703/* Make sure that the correct signer is set. Returns 0 on success. */ 704static int set_signer (gpgme_ctx_t ctx, int for_smime) 705{ 706 char *signid = for_smime ? SmimeDefaultKey: PgpSignAs; 707 gpgme_error_t err; 708 gpgme_ctx_t listctx; 709 gpgme_key_t key, key2; 710 711 if (!signid || !*signid) 712 return 0; 713 714 listctx = create_gpgme_context (for_smime); 715 err = gpgme_op_keylist_start (listctx, signid, 1); 716 if (!err) 717 err = gpgme_op_keylist_next (listctx, &key); 718 if (err) 719 { 720 gpgme_release (listctx); 721 mutt_error (_("secret key `%s' not found: %s\n"), 722 signid, gpgme_strerror (err)); 723 return -1; 724 } 725 err = gpgme_op_keylist_next (listctx, &key2); 726 if (!err) 727 { 728 gpgme_key_unref (key); 729 gpgme_key_unref (key2); 730 gpgme_release (listctx); 731 mutt_error (_("ambiguous specification of secret key `%s'\n"), 732 signid); 733 return -1; 734 } 735 gpgme_op_keylist_end (listctx); 736 gpgme_release (listctx); 737 738 gpgme_signers_clear (ctx); 739 err = gpgme_signers_add (ctx, key); 740 gpgme_key_unref (key); 741 if (err) 742 { 743 mutt_error (_("error setting secret key `%s': %s\n"), 744 signid, gpgme_strerror (err)); 745 return -1; 746 } 747 return 0; 748} 749 750static gpgme_error_t 751set_pka_sig_notation (gpgme_ctx_t ctx) 752{ 753 gpgme_error_t err; 754 755 err = gpgme_sig_notation_add (ctx, 756 PKA_NOTATION_NAME, current_sender, 0); 757 758 if (err) 759 { 760 mutt_error (_("error setting PKA signature notation: %s\n"), 761 gpgme_strerror (err)); 762 mutt_sleep (2); 763 } 764 765 return err; 766} 767 768/* Encrypt the gpgme data object PLAINTEXT to the recipients in RSET 769 and return an allocated filename to a temporary file containing the 770 enciphered text. With USE_SMIME set to true, the smime backend is 771 used. With COMBINED_SIGNED a PGP message is signed and 772 encrypted. Returns NULL in case of error */ 773static char *encrypt_gpgme_object (gpgme_data_t plaintext, gpgme_key_t *rset, 774 int use_smime, int combined_signed) 775{ 776 gpgme_error_t err; 777 gpgme_ctx_t ctx; 778 gpgme_data_t ciphertext; 779 char *outfile; 780 781 ctx = create_gpgme_context (use_smime); 782 if (!use_smime) 783 gpgme_set_armor (ctx, 1); 784 785 ciphertext = create_gpgme_data (); 786 787 if (combined_signed) 788 { 789 if (set_signer (ctx, use_smime)) 790 { 791 gpgme_data_release (ciphertext); 792 gpgme_release (ctx); 793 return NULL; 794 } 795 796 if (option (OPTCRYPTUSEPKA)) 797 { 798 err = set_pka_sig_notation (ctx); 799 if (err) 800 { 801 gpgme_data_release (ciphertext); 802 gpgme_release (ctx); 803 return NULL; 804 } 805 } 806 807 err = gpgme_op_encrypt_sign (ctx, rset, GPGME_ENCRYPT_ALWAYS_TRUST, 808 plaintext, ciphertext); 809 } 810 else 811 err = gpgme_op_encrypt (ctx, rset, GPGME_ENCRYPT_ALWAYS_TRUST, 812 plaintext, ciphertext); 813 mutt_need_hard_redraw (); 814 if (err) 815 { 816 mutt_error (_("error encrypting data: %s\n"), gpgme_strerror (err)); 817 gpgme_data_release (ciphertext); 818 gpgme_release (ctx); 819 return NULL; 820 } 821 822 gpgme_release (ctx); 823 824 outfile = data_object_to_tempfile (ciphertext, NULL, NULL); 825 gpgme_data_release (ciphertext); 826 return outfile; 827} 828 829/* Find the "micalg" parameter from the last Gpgme operation on 830 context CTX. It is expected that this operation was a sign 831 operation. Return the algorithm name as a C string in buffer BUF 832 which must have been allocated by the caller with size BUFLEN. 833 Returns 0 on success or -1 in case of an error. The return string 834 is truncted to BUFLEN - 1. */ 835static int get_micalg (gpgme_ctx_t ctx, int use_smime, char *buf, size_t buflen) 836{ 837 gpgme_sign_result_t result = NULL; 838 const char *algorithm_name = NULL; 839 840 if (buflen < 5) 841 return -1; 842 843 *buf = 0; 844 result = gpgme_op_sign_result (ctx); 845 if (result && result->signatures) 846 { 847 algorithm_name = gpgme_hash_algo_name (result->signatures->hash_algo); 848 if (algorithm_name) 849 { 850 if (use_smime) 851 { 852 /* convert GPGME raw hash name to RFC 2633 format */ 853 snprintf (buf, buflen, "%s", algorithm_name); 854 ascii_strlower (buf); 855 } else { 856 /* convert GPGME raw hash name to RFC 3156 format */ 857 snprintf (buf, buflen, "pgp-%s", algorithm_name); 858 ascii_strlower (buf + 4); 859 } 860 } 861 } 862 863 return *buf? 0:-1; 864} 865 866static void print_time(time_t t, STATE *s) 867{ 868 char p[STRING]; 869 870#ifdef HAVE_LANGINFO_D_T_FMT 871 strftime (p, sizeof (p), nl_langinfo (D_T_FMT), localtime (&t)); 872#else 873 strftime (p, sizeof (p), "%c", localtime (&t)); 874#endif 875 state_puts (p, s); 876} 877 878/* 879 * Implementation of `sign_message'. 880 */ 881 882/* Sign the MESSAGE in body A either using OpenPGP or S/MIME when 883 USE_SMIME is passed as true. Returns the new body or NULL on 884 error. */ 885static BODY *sign_message (BODY *a, int use_smime) 886{ 887 BODY *t; 888 char *sigfile; 889 int err = 0; 890 char buf[100]; 891 gpgme_ctx_t ctx; 892 gpgme_data_t message, signature; 893 gpgme_sign_result_t sigres; 894 895 convert_to_7bit (a); /* Signed data _must_ be in 7-bit format. */ 896 897 message = body_to_data_object (a, 1); 898 if (!message) 899 return NULL; 900 signature = create_gpgme_data (); 901 902 ctx = create_gpgme_context (use_smime); 903 if (!use_smime) 904 gpgme_set_armor (ctx, 1); 905 906 if (set_signer (ctx, use_smime)) 907 { 908 gpgme_data_release (signature); 909 gpgme_data_release (message); 910 gpgme_release (ctx); 911 return NULL; 912 } 913 914 if (option (OPTCRYPTUSEPKA)) 915 { 916 err = set_pka_sig_notation (ctx); 917 if (err) 918 { 919 gpgme_data_release (signature); 920 gpgme_data_release (message); 921 gpgme_release (ctx); 922 return NULL; 923 } 924 } 925 926 err = gpgme_op_sign (ctx, message, signature, GPGME_SIG_MODE_DETACH ); 927 mutt_need_hard_redraw (); 928 gpgme_data_release (message); 929 if (err) 930 { 931 gpgme_data_release (signature); 932 gpgme_release (ctx); 933 mutt_error (_("error signing data: %s\n"), gpgme_strerror (err)); 934 return NULL; 935 } 936 /* Check for zero signatures generated. This can occur when $pgp_sign_as is 937 * unset and there is no default key specified in ~/.gnupg/gpg.conf 938 */ 939 sigres = gpgme_op_sign_result (ctx); 940 if (!sigres->signatures) 941 { 942 gpgme_data_release (signature); 943 gpgme_release (ctx); 944 mutt_error (_("$pgp_sign_as unset and no default key specified in ~/.gnupg/gpg.conf")); 945 return NULL; 946 } 947 948 sigfile = data_object_to_tempfile (signature, NULL, NULL); 949 gpgme_data_release (signature); 950 if (!sigfile) 951 { 952 gpgme_release (ctx); 953 return NULL; 954 } 955 956 t = mutt_new_body (); 957 t->type = TYPEMULTIPART; 958 t->subtype = safe_strdup ("signed"); 959 t->encoding = ENC7BIT; 960 t->use_disp = 0; 961 t->disposition = DISPINLINE; 962 963 mutt_generate_boundary (&t->parameter); 964 mutt_set_parameter ("protocol", 965 use_smime? "application/pkcs7-signature" 966 : "application/pgp-signature", 967 &t->parameter); 968 /* Get the micalg from gpgme. Old gpgme versions don't support this 969 for S/MIME so we assume sha-1 in this case. */ 970 if (!get_micalg (ctx, use_smime, buf, sizeof buf)) 971 mutt_set_parameter ("micalg", buf, &t->parameter); 972 else if (use_smime) 973 mutt_set_parameter ("micalg", "sha1", &t->parameter); 974 gpgme_release (ctx); 975 976 t->parts = a; 977 a = t; 978 979 t->parts->next = mutt_new_body (); 980 t = t->parts->next; 981 t->type = TYPEAPPLICATION; 982 if (use_smime) 983 { 984 t->subtype = safe_strdup ("pkcs7-signature"); 985 mutt_set_parameter ("name", "smime.p7s", &t->parameter); 986 t->encoding = ENCBASE64; 987 t->use_disp = 1; 988 t->disposition = DISPATTACH; 989 t->d_filename = safe_strdup ("smime.p7s"); 990 } 991 else 992 { 993 t->subtype = safe_strdup ("pgp-signature"); 994 mutt_set_parameter ("name", "signature.asc", &t->parameter); 995 t->use_disp = 0; 996 t->disposition = DISPNONE; 997 t->encoding = ENC7BIT; 998 } 999 t->filename = sigfile; 1000 t->unlink = 1; /* ok to remove this file after sending. */ 1001 1002 return a; 1003} 1004 1005 1006BODY *pgp_gpgme_sign_message (BODY *a) 1007{ 1008 return sign_message (a, 0); 1009} 1010 1011BODY *smime_gpgme_sign_message (BODY *a) 1012{ 1013 return sign_message (a, 1); 1014} 1015 1016/* 1017 * Implementation of `encrypt_message'. 1018 */ 1019 1020/* Encrypt the mail body A to all keys given as space separated keyids 1021 or fingerprints in KEYLIST and return the encrypted body. */ 1022BODY *pgp_gpgme_encrypt_message (BODY *a, char *keylist, int sign) 1023{ 1024 char *outfile = NULL; 1025 BODY *t; 1026 gpgme_key_t *rset = NULL; 1027 gpgme_data_t plaintext; 1028 1029 rset = create_recipient_set (keylist, GPGME_PROTOCOL_OpenPGP); 1030 if (!rset) 1031 return NULL; 1032 1033 if (sign) 1034 convert_to_7bit (a); 1035 plaintext = body_to_data_object (a, 0); 1036 if (!plaintext) 1037 { 1038 free_recipient_set (&rset); 1039 return NULL; 1040 } 1041 1042 outfile = encrypt_gpgme_object (plaintext, rset, 0, sign); 1043 gpgme_data_release (plaintext); 1044 free_recipient_set (&rset); 1045 if (!outfile) 1046 return NULL; 1047 1048 t = mutt_new_body (); 1049 t->type = TYPEMULTIPART; 1050 t->subtype = safe_strdup ("encrypted"); 1051 t->encoding = ENC7BIT; 1052 t->use_disp = 0; 1053 t->disposition = DISPINLINE; 1054 1055 mutt_generate_boundary(&t->parameter); 1056 mutt_set_parameter("protocol", "application/pgp-encrypted", &t->parameter); 1057 1058 t->parts = mutt_new_body (); 1059 t->parts->type = TYPEAPPLICATION; 1060 t->parts->subtype = safe_strdup ("pgp-encrypted"); 1061 t->parts->encoding = ENC7BIT; 1062 1063 t->parts->next = mutt_new_body (); 1064 t->parts->next->type = TYPEAPPLICATION; 1065 t->parts->next->subtype = safe_strdup ("octet-stream"); 1066 t->parts->next->encoding = ENC7BIT; 1067 t->parts->next->filename = outfile; 1068 t->parts->next->use_disp = 1; 1069 t->parts->next->disposition = DISPATTACH; 1070 t->parts->next->unlink = 1; /* delete after sending the message */ 1071 t->parts->next->d_filename = safe_strdup ("msg.asc"); /* non pgp/mime 1072 can save */ 1073 1074 return t; 1075} 1076 1077/* 1078 * Implementation of `smime_build_smime_entity'. 1079 */ 1080 1081/* Encrypt the mail body A to all keys given as space separated 1082 fingerprints in KEYLIST and return the S/MIME encrypted body. */ 1083BODY *smime_gpgme_build_smime_entity (BODY *a, char *keylist) 1084{ 1085 char *outfile = NULL; 1086 BODY *t; 1087 gpgme_key_t *rset = NULL; 1088 gpgme_data_t plaintext; 1089 1090 rset = create_recipient_set (keylist, GPGME_PROTOCOL_CMS); 1091 if (!rset) 1092 return NULL; 1093 1094 /* OpenSSL converts line endings to crlf when encrypting. Some 1095 * clients depend on this for signed+encrypted messages: they do not 1096 * convert line endings between decrypting and checking the 1097 * signature. See #3904. */ 1098 plaintext = body_to_data_object (a, 1); 1099 if (!plaintext) 1100 { 1101 free_recipient_set (&rset); 1102 return NULL; 1103 } 1104 1105 outfile = encrypt_gpgme_object (plaintext, rset, 1, 0); 1106 gpgme_data_release (plaintext); 1107 free_recipient_set (&rset); 1108 if (!outfile) 1109 return NULL; 1110 1111 t = mutt_new_body (); 1112 t->type = TYPEAPPLICATION; 1113 t->subtype = safe_strdup ("pkcs7-mime"); 1114 mutt_set_parameter ("name", "smime.p7m", &t->parameter); 1115 mutt_set_parameter ("smime-type", "enveloped-data", &t->parameter); 1116 t->encoding = ENCBASE64; /* The output of OpenSSL SHOULD be binary */ 1117 t->use_disp = 1; 1118 t->disposition = DISPATTACH; 1119 t->d_filename = safe_strdup ("smime.p7m"); 1120 t->filename = outfile; 1121 t->unlink = 1; /*delete after sending the message */ 1122 t->parts=0; 1123 t->next=0; 1124 1125 return t; 1126} 1127 1128 1129/* 1130 * Implementation of `verify_one'. 1131 */ 1132 1133/* Display the common attributes of the signature summary SUM. 1134 Return 1 if there is is a severe warning. 1135 */ 1136static int show_sig_summary (unsigned long sum, 1137 gpgme_ctx_t ctx, gpgme_key_t key, int idx, 1138 STATE *s, gpgme_signature_t sig) 1139{ 1140 int severe = 0; 1141 1142 if ((sum & GPGME_SIGSUM_KEY_REVOKED)) 1143 { 1144 state_puts (_("Warning: One of the keys has been revoked\n"),s); 1145 severe = 1; 1146 } 1147 1148 if ((sum & GPGME_SIGSUM_KEY_EXPIRED)) 1149 { 1150 time_t at = key->subkeys->expires ? key->subkeys->expires : 0; 1151 if (at) 1152 { 1153 state_puts (_("Warning: The key used to create the " 1154 "signature expired at: "), s); 1155 print_time (at , s); 1156 state_puts ("\n", s); 1157 } 1158 else 1159 state_puts (_("Warning: At least one certification key " 1160 "has expired\n"), s); 1161 } 1162 1163 if ((sum & GPGME_SIGSUM_SIG_EXPIRED)) 1164 { 1165 gpgme_verify_result_t result; 1166 gpgme_signature_t sig; 1167 unsigned int i; 1168 1169 result = gpgme_op_verify_result (ctx); 1170 1171 for (sig = result->signatures, i = 0; sig && (i < idx); 1172 sig = sig->next, i++) 1173 ; 1174 1175 state_puts (_("Warning: The signature expired at: "), s); 1176 print_time (sig ? sig->exp_timestamp : 0, s); 1177 state_puts ("\n", s); 1178 } 1179 1180 if ((sum & GPGME_SIGSUM_KEY_MISSING)) 1181 state_puts (_("Can't verify due to a missing " 1182 "key or certificate\n"), s); 1183 1184 if ((sum & GPGME_SIGSUM_CRL_MISSING)) 1185 { 1186 state_puts (_("The CRL is not available\n"), s); 1187 severe = 1; 1188 } 1189 1190 if ((sum & GPGME_SIGSUM_CRL_TOO_OLD)) 1191 { 1192 state_puts (_("Available CRL is too old\n"), s); 1193 severe = 1; 1194 } 1195 1196 if ((sum & GPGME_SIGSUM_BAD_POLICY)) 1197 state_puts (_("A policy requirement was not met\n"), s); 1198 1199 if ((sum & GPGME_SIGSUM_SYS_ERROR)) 1200 { 1201 const char *t0 = NULL, *t1 = NULL; 1202 gpgme_verify_result_t result; 1203 gpgme_signature_t sig; 1204 unsigned int i; 1205 1206 state_puts (_("A system error occurred"), s ); 1207 1208 /* Try to figure out some more detailed system error information. */ 1209 result = gpgme_op_verify_result (ctx); 1210 for (sig = result->signatures, i = 0; sig && (i < idx); 1211 sig = sig->next, i++) 1212 ; 1213 if (sig) 1214 { 1215 t0 = ""; 1216 t1 = sig->wrong_key_usage ? "Wrong_Key_Usage" : ""; 1217 } 1218 1219 if (t0 || t1) 1220 { 1221 state_puts (": ", s); 1222 if (t0) 1223 state_puts (t0, s); 1224 if (t1 && !(t0 && !strcmp (t0, t1))) 1225 { 1226 if (t0) 1227 state_puts (",", s); 1228 state_puts (t1, s); 1229 } 1230 } 1231 state_puts ("\n", s); 1232 } 1233 1234#ifdef HAVE_GPGME_PKA_TRUST 1235 1236 if (option (OPTCRYPTUSEPKA)) 1237 { 1238 if (sig->pka_trust == 1 && sig->pka_address) 1239 { 1240 state_puts (_("WARNING: PKA entry does not match " 1241 "signer's address: "), s); 1242 state_puts (sig->pka_address, s); 1243 state_puts ("\n", s); 1244 } 1245 else if (sig->pka_trust == 2 && sig->pka_address) 1246 { 1247 state_puts (_("PKA verified signer's address is: "), s); 1248 state_puts (sig->pka_address, s); 1249 state_puts ("\n", s); 1250 } 1251 } 1252 1253#endif 1254 1255 return severe; 1256} 1257 1258 1259static void show_fingerprint (gpgme_key_t key, STATE *state) 1260{ 1261 const char *s; 1262 int i, is_pgp; 1263 char *buf, *p; 1264 const char *prefix = _("Fingerprint: "); 1265 1266 if (!key) 1267 return; 1268 s = key->subkeys ? key->subkeys->fpr : NULL; 1269 if (!s) 1270 return; 1271 is_pgp = (key->protocol == GPGME_PROTOCOL_OpenPGP); 1272 1273 buf = safe_malloc ( strlen (prefix) + strlen(s) * 4 + 2 ); 1274 strcpy (buf, prefix); /* __STRCPY_CHECKED__ */ 1275 p = buf + strlen (buf); 1276 if (is_pgp && strlen (s) == 40) 1277 { /* PGP v4 style formatted. */ 1278 for (i=0; *s && s[1] && s[2] && s[3] && s[4]; s += 4, i++) 1279 { 1280 *p++ = s[0]; 1281 *p++ = s[1]; 1282 *p++ = s[2]; 1283 *p++ = s[3]; 1284 *p++ = ' '; 1285 if (i == 4) 1286 *p++ = ' '; 1287 } 1288 } 1289 else 1290 { 1291 for (i=0; *s && s[1] && s[2]; s += 2, i++) 1292 { 1293 *p++ = s[0]; 1294 *p++ = s[1]; 1295 *p++ = is_pgp? ' ':':'; 1296 if (is_pgp && i == 7) 1297 *p++ = ' '; 1298 } 1299 } 1300 1301 /* just in case print remaining odd digits */ 1302 for (; *s; s++) 1303 *p++ = *s; 1304 *p++ = '\n'; 1305 *p = 0; 1306 state_puts (buf, state); 1307 FREE (&buf); 1308} 1309 1310/* Show the validity of a key used for one signature. */ 1311static void show_one_sig_validity (gpgme_ctx_t ctx, int idx, STATE *s) 1312{ 1313 gpgme_verify_result_t result = NULL; 1314 gpgme_signature_t sig = NULL; 1315 const char *txt = NULL; 1316 1317 result = gpgme_op_verify_result (ctx); 1318 if (result) 1319 for (sig = result->signatures; sig && (idx > 0); sig = sig->next, idx--); 1320 1321 switch (sig ? sig->validity : 0) 1322 { 1323 case GPGME_VALIDITY_UNKNOWN: 1324 txt = _("WARNING: We have NO indication whether " 1325 "the key belongs to the person named " 1326 "as shown above\n"); 1327 break; 1328 case GPGME_VALIDITY_UNDEFINED: 1329 break; 1330 case GPGME_VALIDITY_NEVER: 1331 txt = _("WARNING: The key does NOT BELONG to " 1332 "the person named as shown above\n"); 1333 break; 1334 case GPGME_VALIDITY_MARGINAL: 1335 txt = _("WARNING: It is NOT certain that the key " 1336 "belongs to the person named as shown above\n"); 1337 break; 1338 case GPGME_VALIDITY_FULL: 1339 case GPGME_VALIDITY_ULTIMATE: 1340 txt = NULL; 1341 break; 1342 } 1343 if (txt) 1344 state_puts (txt, s); 1345} 1346 1347static void print_smime_keyinfo (const char* msg, gpgme_signature_t sig, 1348 gpgme_key_t key, STATE *s) 1349{ 1350 int msgwid; 1351 gpgme_user_id_t uids = NULL; 1352 int i, aka = 0; 1353 1354 state_puts (msg, s); 1355 state_puts (" ", s); 1356 /* key is NULL when not present in the user's keyring */ 1357 if (key) 1358 { 1359 for (uids = key->uids; uids; uids = uids->next) 1360 { 1361 if (uids->revoked) 1362 continue; 1363 if (aka) 1364 { 1365 msgwid = mutt_strwidth (msg) - mutt_strwidth (_("aka: ")) + 1; 1366 if (msgwid < 0) 1367 msgwid = 0; 1368 for (i = 0; i < msgwid; i++) 1369 state_puts(" ", s); 1370 state_puts(_("aka: "), s); 1371 } 1372 state_puts (uids->uid, s); 1373 state_puts ("\n", s); 1374 1375 aka = 1; 1376 } 1377 } 1378 else 1379 { 1380 state_puts (_("KeyID "), s); 1381 state_puts (sig->fpr, s); 1382 state_puts ("\n", s); 1383 } 1384 1385 /* timestamp is 0 when verification failed. 1386 "Jan 1 1970" is not the created date. */ 1387 if (sig->timestamp) 1388 { 1389 msgwid = mutt_strwidth (msg) - mutt_strwidth (_("created: ")) + 1; 1390 if (msgwid < 0) 1391 msgwid = 0; 1392 for (i = 0; i < msgwid; i++) 1393 state_puts(" ", s); 1394 state_puts (_("created: "), s); 1395 print_time (sig->timestamp, s); 1396 state_puts ("\n", s); 1397 } 1398} 1399 1400/* Show information about one signature. This function is called with 1401 the context CTX of a successful verification operation and the 1402 enumerator IDX which should start at 0 and increment for each 1403 call/signature. 1404 1405 Return values are: 0 for normal procession, 1 for a bad signature, 1406 2 for a signature with a warning or -1 for no more signature. */ 1407static int show_one_sig_status (gpgme_ctx_t ctx, int idx, STATE *s) 1408{ 1409 const char *fpr; 1410 gpgme_key_t key = NULL; 1411 int i, anybad = 0, anywarn = 0; 1412 unsigned int sum; 1413 gpgme_verify_result_t result; 1414 gpgme_signature_t sig; 1415 gpgme_error_t err = GPG_ERR_NO_ERROR; 1416 char buf[LONG_STRING]; 1417 1418 result = gpgme_op_verify_result (ctx); 1419 if (result) 1420 { 1421 /* FIXME: this code should use a static variable and remember 1422 the current position in the list of signatures, IMHO. 1423 -moritz. */ 1424 1425 for (i = 0, sig = result->signatures; sig && (i < idx); 1426 i++, sig = sig->next) 1427 ; 1428 if (! sig) 1429 return -1; /* Signature not found. */ 1430 1431 if (signature_key) 1432 { 1433 gpgme_key_unref (signature_key); 1434 signature_key = NULL; 1435 } 1436 1437 fpr = sig->fpr; 1438 sum = sig->summary; 1439 1440 if (gpg_err_code (sig->status) != GPG_ERR_NO_ERROR) 1441 anybad = 1; 1442 1443 if (gpg_err_code (sig->status) != GPG_ERR_NO_PUBKEY) 1444 { 1445 err = gpgme_get_key (ctx, fpr, &key, 0); /* secret key? */ 1446 if (! err) 1447 { 1448 if (! signature_key) 1449 signature_key = key; 1450 } 1451 else 1452 { 1453 key = NULL; /* Old gpgme versions did not set KEY to NULL on 1454 error. Do it here to avoid a double free. */ 1455 } 1456 } 1457 else 1458 { 1459 /* pubkey not present */ 1460 } 1461 1462 if (!s || !s->fpout || !(s->flags & MUTT_DISPLAY)) 1463 ; /* No state information so no way to print anything. */ 1464 else if (err) 1465 { 1466 snprintf (buf, sizeof (buf), 1467 _("Error getting key information for KeyID %s: %s\n"), 1468 fpr, gpgme_strerror (err)); 1469 state_puts (buf, s); 1470 anybad = 1; 1471 } 1472 else if ((sum & GPGME_SIGSUM_GREEN)) 1473 { 1474 print_smime_keyinfo (_("Good signature from:"), sig, key, s); 1475 if (show_sig_summary (sum, ctx, key, idx, s, sig)) 1476 anywarn = 1; 1477 show_one_sig_validity (ctx, idx, s); 1478 } 1479 else if ((sum & GPGME_SIGSUM_RED)) 1480 { 1481 print_smime_keyinfo (_("*BAD* signature from:"), sig, key, s); 1482 show_sig_summary (sum, ctx, key, idx, s, sig); 1483 } 1484 else if (!anybad && key && (key->protocol == GPGME_PROTOCOL_OpenPGP)) 1485 { /* We can't decide (yellow) but this is a PGP key with a good 1486 signature, so we display what a PGP user expects: The name, 1487 fingerprint and the key validity (which is neither fully or 1488 ultimate). */ 1489 print_smime_keyinfo (_("Good signature from:"), sig, key, s); 1490 show_one_sig_validity (ctx, idx, s); 1491 show_fingerprint (key,s); 1492 if (show_sig_summary (sum, ctx, key, idx, s, sig)) 1493 anywarn = 1; 1494 } 1495 else /* can't decide (yellow) */ 1496 { 1497 print_smime_keyinfo (_("Problem signature from:"), sig, key, s); 1498 /* 0 indicates no expiration */ 1499 if (sig->exp_timestamp) 1500 { 1501 /* L10N: 1502 This is trying to match the width of the 1503 "Problem signature from:" translation just above. */ 1504 state_puts (_(" expires: "), s); 1505 print_time (sig->exp_timestamp, s); 1506 state_puts ("\n", s); 1507 } 1508 show_sig_summary (sum, ctx, key, idx, s, sig); 1509 anywarn = 1; 1510 } 1511 1512 if (key != signature_key) 1513 gpgme_key_unref (key); 1514 } 1515 1516 return anybad ? 1 : anywarn ? 2 : 0; 1517} 1518 1519/* Do the actual verification step. With IS_SMIME set to true we 1520 assume S/MIME (surprise!) */ 1521static int verify_one (BODY *sigbdy, STATE *s, 1522 const char *tempfile, int is_smime) 1523{ 1524 int badsig = -1; 1525 int anywarn = 0; 1526 int err; 1527 gpgme_ctx_t ctx; 1528 gpgme_data_t signature, message; 1529 1530 signature = file_to_data_object (s->fpin, sigbdy->offset, sigbdy->length); 1531 if (!signature) 1532 return -1; 1533 1534 /* We need to tell gpgme about the encoding because the backend can't 1535 auto-detect plain base-64 encoding which is used by S/MIME. */ 1536 if (is_smime) 1537 gpgme_data_set_encoding (signature, GPGME_DATA_ENCODING_BASE64); 1538 1539 err = gpgme_data_new_from_file (&message, tempfile, 1); 1540 if (err) 1541 { 1542 gpgme_data_release (signature); 1543 mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err)); 1544 return -1; 1545 } 1546 ctx = create_gpgme_context (is_smime); 1547 1548 /* Note: We don't need a current time output because GPGME avoids 1549 such an attack by separating the meta information from the 1550 data. */ 1551 state_attach_puts (_("[-- Begin signature information --]\n"), s); 1552 1553 err = gpgme_op_verify (ctx, signature, message, NULL); 1554 gpgme_data_release (message); 1555 gpgme_data_release (signature); 1556 1557 mutt_need_hard_redraw (); 1558 if (err) 1559 { 1560 char buf[200]; 1561 1562 snprintf (buf, sizeof(buf)-1, 1563 _("Error: verification failed: %s\n"), 1564 gpgme_strerror (err)); 1565 state_puts (buf, s); 1566 } 1567 else 1568 { /* Verification succeeded, see what the result is. */ 1569 int res, idx; 1570 int anybad = 0; 1571 gpgme_verify_result_t verify_result; 1572 1573 if (signature_key) 1574 { 1575 gpgme_key_unref (signature_key); 1576 signature_key = NULL; 1577 } 1578 1579 verify_result = gpgme_op_verify_result (ctx); 1580 if (verify_result && verify_result->signatures) 1581 { 1582 for (idx=0; (res = show_one_sig_status (ctx, idx, s)) != -1; idx++) 1583 { 1584 if (res == 1) 1585 anybad = 1; 1586 else if (res == 2) 1587 anywarn = 2; 1588 } 1589 if (!anybad) 1590 badsig = 0; 1591 } 1592 } 1593 1594 if (!badsig) 1595 { 1596 gpgme_verify_result_t result; 1597 gpgme_sig_notation_t notation; 1598 gpgme_signature_t signature; 1599 int non_pka_notations; 1600 1601 result = gpgme_op_verify_result (ctx); 1602 if (result) 1603 { 1604 for (signature = result->signatures; signature; 1605 signature = signature->next) 1606 { 1607 non_pka_notations = 0; 1608 for (notation = signature->notations; notation; 1609 notation = notation->next) 1610 if (! is_pka_notation (notation)) 1611 non_pka_notations++; 1612 1613 if (non_pka_notations) 1614 { 1615 char buf[SHORT_STRING]; 1616 snprintf (buf, sizeof (buf), 1617 _("*** Begin Notation (signature by: %s) ***\n"), 1618 signature->fpr); 1619 state_puts (buf, s); 1620 for (notation = signature->notations; notation; 1621 notation = notation->next) 1622 { 1623 if (is_pka_notation (notation)) 1624 continue; 1625 1626 if (notation->name) 1627 { 1628 state_puts (notation->name, s); 1629 state_puts ("=", s); 1630 } 1631 if (notation->value) 1632 { 1633 state_puts (notation->value, s); 1634 if (!(*notation->value 1635 && (notation->value[strlen (notation->value)-1]=='\n'))) 1636 state_puts ("\n", s); 1637 } 1638 } 1639 state_puts (_("*** End Notation ***\n"), s); 1640 } 1641 } 1642 } 1643 } 1644 1645 gpgme_release (ctx); 1646 1647 state_attach_puts (_("[-- End signature information --]\n\n"), s); 1648 dprint (1, (debugfile, "verify_one: returning %d.\n", badsig)); 1649 1650 return badsig? 1: anywarn? 2 : 0; 1651} 1652 1653int pgp_gpgme_verify_one (BODY *sigbdy, STATE *s, const char *tempfile) 1654{ 1655 return verify_one (sigbdy, s, tempfile, 0); 1656} 1657 1658int smime_gpgme_verify_one (BODY *sigbdy, STATE *s, const char *tempfile) 1659{ 1660 return verify_one (sigbdy, s, tempfile, 1); 1661} 1662 1663/* 1664 * Implementation of `decrypt_part'. 1665 */ 1666 1667/* Decrypt a PGP or SMIME message (depending on the boolean flag 1668 IS_SMIME) with body A described further by state S. Write 1669 plaintext out to file FPOUT and return a new body. For PGP returns 1670 a flag in R_IS_SIGNED to indicate whether this is a combined 1671 encrypted and signed message, for S/MIME it returns true when it is 1672 not a encrypted but a signed message. */ 1673static BODY *decrypt_part (BODY *a, STATE *s, FILE *fpout, int is_smime, 1674 int *r_is_signed) 1675{ 1676 struct stat info; 1677 BODY *tattach; 1678 int err = 0; 1679 gpgme_ctx_t ctx; 1680 gpgme_data_t ciphertext, plaintext; 1681 int maybe_signed = 0; 1682 int anywarn = 0; 1683 int sig_stat = 0; 1684 1685 if (r_is_signed) 1686 *r_is_signed = 0; 1687 1688 ctx = create_gpgme_context (is_smime); 1689 1690 restart: 1691 /* Make a data object from the body, create context etc. */ 1692 ciphertext = file_to_data_object (s->fpin, a->offset, a->length); 1693 if (!ciphertext) 1694 return NULL; 1695 plaintext = create_gpgme_data (); 1696 1697 /* Do the decryption or the verification in case of the S/MIME hack. */ 1698 if ((! is_smime) || maybe_signed) 1699 { 1700 if (! is_smime) 1701 err = gpgme_op_decrypt_verify (ctx, ciphertext, plaintext); 1702 else if (maybe_signed) 1703 err = gpgme_op_verify (ctx, ciphertext, NULL, plaintext); 1704 1705 if (err == GPG_ERR_NO_ERROR) 1706 { 1707 /* Check whether signatures have been verified. */ 1708 gpgme_verify_result_t verify_result = gpgme_op_verify_result (ctx); 1709 if (verify_result->signatures) 1710 sig_stat = 1; 1711 } 1712 } 1713 else 1714 err = gpgme_op_decrypt (ctx, ciphertext, plaintext); 1715 gpgme_data_release (ciphertext); 1716 if (err) 1717 { 1718 if (is_smime && !maybe_signed 1719 && gpg_err_code (err) == GPG_ERR_NO_DATA) 1720 { 1721 /* Check whether this might be a signed message despite what 1722 the mime header told us. Retry then. gpgsm returns the 1723 error information "unsupported Algorithm '?'" but gpgme 1724 will not store this unknown algorithm, thus we test that 1725 it has not been set. */ 1726 gpgme_decrypt_result_t result; 1727 1728 result = gpgme_op_decrypt_result (ctx); 1729 if (!result->unsupported_algorithm) 1730 { 1731 maybe_signed = 1; 1732 gpgme_data_release (plaintext); 1733 goto restart; 1734 } 1735 } 1736 mutt_need_hard_redraw (); 1737 if ((s->flags & MUTT_DISPLAY)) 1738 { 1739 char buf[200]; 1740 1741 snprintf (buf, sizeof(buf)-1, 1742 _("[-- Error: decryption failed: %s --]\n\n"), 1743 gpgme_strerror (err)); 1744 state_attach_puts (buf, s); 1745 } 1746 gpgme_data_release (plaintext); 1747 gpgme_release (ctx); 1748 return NULL; 1749 } 1750 mutt_need_hard_redraw (); 1751 1752 /* Read the output from GPGME, and make sure to change CRLF to LF, 1753 otherwise read_mime_header has a hard time parsing the message. */ 1754 if (data_object_to_stream (plaintext, fpout)) 1755 { 1756 gpgme_data_release (plaintext); 1757 gpgme_release (ctx); 1758 return NULL; 1759 } 1760 gpgme_data_release (plaintext); 1761 1762 a->is_signed_data = 0; 1763 if (sig_stat) 1764 { 1765 int res, idx; 1766 int anybad = 0; 1767 1768 if (maybe_signed) 1769 a->is_signed_data = 1; 1770 if(r_is_signed) 1771 *r_is_signed = -1; /* A signature exists. */ 1772 1773 if ((s->flags & MUTT_DISPLAY)) 1774 state_attach_puts (_("[-- Begin signature " 1775 "information --]\n"), s); 1776 for(idx = 0; (res = show_one_sig_status (ctx, idx, s)) != -1; idx++) 1777 { 1778 if (res == 1) 1779 anybad = 1; 1780 else if (res == 2) 1781 anywarn = 1; 1782 } 1783 if (!anybad && idx && r_is_signed && *r_is_signed) 1784 *r_is_signed = anywarn? 2:1; /* Good signature. */ 1785 1786 if ((s->flags & MUTT_DISPLAY)) 1787 state_attach_puts (_("[-- End signature " 1788 "information --]\n\n"), s); 1789 } 1790 gpgme_release (ctx); ctx = NULL; 1791 1792 fflush (fpout); 1793 rewind (fpout); 1794 tattach = mutt_read_mime_header (fpout, 0); 1795 if (tattach) 1796 { 1797 /* 1798 * Need to set the length of this body part. 1799 */ 1800 fstat (fileno (fpout), &info); 1801 tattach->length = info.st_size - tattach->offset; 1802 1803 tattach->warnsig = anywarn; 1804 1805 /* See if we need to recurse on this MIME part. */ 1806 mutt_parse_part (fpout, tattach); 1807 } 1808 1809 return tattach; 1810} 1811 1812/* Decrypt a PGP/MIME message in FPIN and B and return a new body and 1813 the stream in CUR and FPOUT. Returns 0 on success. */ 1814int pgp_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur) 1815{ 1816 char tempfile[_POSIX_PATH_MAX]; 1817 STATE s; 1818 BODY *first_part = b; 1819 int is_signed = 0; 1820 int need_decode = 0; 1821 int saved_type; 1822 LOFF_T saved_offset; 1823 size_t saved_length; 1824 FILE *decoded_fp = NULL; 1825 int rv = 0; 1826 1827 first_part->goodsig = 0; 1828 first_part->warnsig = 0; 1829 1830 if (mutt_is_valid_multipart_pgp_encrypted (b)) 1831 b = b->parts->next; 1832 else if (mutt_is_malformed_multipart_pgp_encrypted (b)) 1833 { 1834 b = b->parts->next->next; 1835 need_decode = 1; 1836 } 1837 else 1838 return -1; 1839 1840 memset (&s, 0, sizeof (s)); 1841 s.fpin = fpin; 1842 1843 if (need_decode) 1844 { 1845 saved_type = b->type; 1846 saved_offset = b->offset; 1847 saved_length = b->length; 1848 1849 mutt_mktemp (tempfile, sizeof (tempfile)); 1850 if ((decoded_fp = safe_fopen (tempfile, "w+")) == NULL) 1851 { 1852 mutt_perror (tempfile); 1853 return (-1); 1854 } 1855 unlink (tempfile); 1856 1857 fseeko (s.fpin, b->offset, 0); 1858 s.fpout = decoded_fp; 1859 1860 mutt_decode_attachment (b, &s); 1861 1862 fflush (decoded_fp); 1863 b->length = ftello (decoded_fp); 1864 b->offset = 0; 1865 rewind (decoded_fp); 1866 s.fpin = decoded_fp; 1867 s.fpout = 0; 1868 } 1869 1870 mutt_mktemp (tempfile, sizeof (tempfile)); 1871 if (!(*fpout = safe_fopen (tempfile, "w+"))) 1872 { 1873 mutt_perror (tempfile); 1874 rv = -1; 1875 goto bail; 1876 } 1877 unlink (tempfile); 1878 1879 if ((*cur = decrypt_part (b, &s, *fpout, 0, &is_signed)) == NULL) 1880 rv = -1; 1881 rewind (*fpout); 1882 if (is_signed > 0) 1883 first_part->goodsig = 1; 1884 1885bail: 1886 if (need_decode) 1887 { 1888 b->type = saved_type; 1889 b->length = saved_length; 1890 b->offset = saved_offset; 1891 safe_fclose (&decoded_fp); 1892 } 1893 1894 return rv; 1895} 1896 1897 1898/* Decrypt a S/MIME message in FPIN and B and return a new body and 1899 the stream in CUR and FPOUT. Returns 0 on success. */ 1900int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur) 1901{ 1902 char tempfile[_POSIX_PATH_MAX]; 1903 STATE s; 1904 FILE *tmpfp=NULL; 1905 int is_signed; 1906 LOFF_T saved_b_offset; 1907 size_t saved_b_length; 1908 int saved_b_type; 1909 1910 if (!mutt_is_application_smime (b)) 1911 return -1; 1912 1913 if (b->parts) 1914 return -1; 1915 1916 /* Decode the body - we need to pass binary CMS to the 1917 backend. The backend allows for Base64 encoded data but it does 1918 not allow for QP which I have seen in some messages. So better 1919 do it here. */ 1920 saved_b_type = b->type; 1921 saved_b_offset = b->offset; 1922 saved_b_length = b->length; 1923 memset (&s, 0, sizeof (s)); 1924 s.fpin = fpin; 1925 fseeko (s.fpin, b->offset, 0); 1926 mutt_mktemp (tempfile, sizeof (tempfile)); 1927 if (!(tmpfp = safe_fopen (tempfile, "w+"))) 1928 { 1929 mutt_perror (tempfile); 1930 return -1; 1931 } 1932 mutt_unlink (tempfile); 1933 1934 s.fpout = tmpfp; 1935 mutt_decode_attachment (b, &s); 1936 fflush (tmpfp); 1937 b->length = ftello (s.fpout); 1938 b->offset = 0; 1939 rewind (tmpfp); 1940 1941 memset (&s, 0, sizeof (s)); 1942 s.fpin = tmpfp; 1943 s.fpout = 0; 1944 mutt_mktemp (tempfile, sizeof (tempfile)); 1945 if (!(*fpout = safe_fopen (tempfile, "w+"))) 1946 { 1947 mutt_perror (tempfile); 1948 return -1; 1949 } 1950 mutt_unlink (tempfile); 1951 1952 *cur = decrypt_part (b, &s, *fpout, 1, &is_signed); 1953 if (*cur) 1954 (*cur)->goodsig = is_signed > 0; 1955 b->type = saved_b_type; 1956 b->length = saved_b_length; 1957 b->offset = saved_b_offset; 1958 safe_fclose (&tmpfp); 1959 rewind (*fpout); 1960 if (*cur && !is_signed && !(*cur)->parts && mutt_is_application_smime (*cur)) 1961 { 1962 /* Assume that this is a opaque signed s/mime message. This is 1963 an ugly way of doing it but we have anyway a problem with 1964 arbitrary encoded S/MIME messages: Only the outer part may be 1965 encrypted. The entire mime parsing should be revamped, 1966 probably by keeping the temporary files so that we don't 1967 need to decrypt them all the time. Inner parts of an 1968 encrypted part can then point into this file and there won't 1969 ever be a need to decrypt again. This needs a partial 1970 rewrite of the MIME engine. */ 1971 BODY *bb = *cur; 1972 BODY *tmp_b; 1973 1974 saved_b_type = bb->type; 1975 saved_b_offset = bb->offset; 1976 saved_b_length = bb->length; 1977 memset (&s, 0, sizeof (s)); 1978 s.fpin = *fpout; 1979 fseeko (s.fpin, bb->offset, 0); 1980 mutt_mktemp (tempfile, sizeof (tempfile)); 1981 if (!(tmpfp = safe_fopen (tempfile, "w+"))) 1982 { 1983 mutt_perror (tempfile); 1984 return -1; 1985 } 1986 mutt_unlink (tempfile); 1987 1988 s.fpout = tmpfp; 1989 mutt_decode_attachment (bb, &s); 1990 fflush (tmpfp); 1991 bb->length = ftello (s.fpout); 1992 bb->offset = 0; 1993 rewind (tmpfp); 1994 safe_fclose (fpout); 1995 1996 memset (&s, 0, sizeof (s)); 1997 s.fpin = tmpfp; 1998 s.fpout = 0; 1999 mutt_mktemp (tempfile, sizeof (tempfile)); 2000 if (!(*fpout = safe_fopen (tempfile, "w+"))) 2001 { 2002 mutt_perror (tempfile); 2003 return -1; 2004 } 2005 mutt_unlink (tempfile); 2006 2007 tmp_b = decrypt_part (bb, &s, *fpout, 1, &is_signed); 2008 if (tmp_b) 2009 tmp_b->goodsig = is_signed > 0; 2010 bb->type = saved_b_type; 2011 bb->length = saved_b_length; 2012 bb->offset = saved_b_offset; 2013 safe_fclose (&tmpfp); 2014 rewind (*fpout); 2015 mutt_free_body (cur); 2016 *cur = tmp_b; 2017 } 2018 return *cur? 0:-1; 2019} 2020 2021static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun) 2022{ 2023 /* there's no side-effect free way to view key data in GPGME, 2024 * so we import the key into a temporary keyring */ 2025 char tmpdir[_POSIX_PATH_MAX]; 2026 char tmpfile[_POSIX_PATH_MAX]; 2027 gpgme_ctx_t tmpctx; 2028 gpgme_error_t err; 2029 gpgme_engine_info_t engineinfo; 2030 gpgme_key_t key; 2031 gpgme_user_id_t uid; 2032 gpgme_subkey_t subkey; 2033 const char* shortid; 2034 int len; 2035 char date[STRING]; 2036 int more; 2037 int rc = -1; 2038 time_t tt; 2039 2040 if ((err = gpgme_new (&tmpctx)) != GPG_ERR_NO_ERROR) 2041 { 2042 dprint (1, (debugfile, "Error creating GPGME context\n")); 2043 return rc; 2044 } 2045 2046 if (dryrun) 2047 { 2048 snprintf (tmpdir, sizeof(tmpdir), "%s/mutt-gpgme-XXXXXX", Tempdir); 2049 if (!mkdtemp (tmpdir)) 2050 { 2051 dprint (1, (debugfile, "Error creating temporary GPGME home\n")); 2052 goto err_ctx; 2053 } 2054 2055 engineinfo = gpgme_ctx_get_engine_info (tmpctx); 2056 while (engineinfo && engineinfo->protocol != GPGME_PROTOCOL_OpenPGP) 2057 engineinfo = engineinfo->next; 2058 if (!engineinfo) 2059 { 2060 dprint (1, (debugfile, "Error finding GPGME PGP engine\n")); 2061 goto err_tmpdir; 2062 } 2063 2064 err = gpgme_ctx_set_engine_info (tmpctx, GPGME_PROTOCOL_OpenPGP, 2065 engineinfo->file_name, tmpdir); 2066 if (err != GPG_ERR_NO_ERROR) 2067 { 2068 dprint (1, (debugfile, "Error setting GPGME context home\n")); 2069 goto err_tmpdir; 2070 } 2071 } 2072 2073 if ((err = gpgme_op_import (tmpctx, keydata)) != GPG_ERR_NO_ERROR) 2074 { 2075 dprint (1, (debugfile, "Error importing key\n")); 2076 goto err_tmpdir; 2077 } 2078 2079 mutt_mktemp (tmpfile, sizeof (tmpfile)); 2080 *fp = safe_fopen (tmpfile, "w+"); 2081 if (!*fp) 2082 { 2083 mutt_perror (tmpfile); 2084 goto err_tmpdir; 2085 } 2086 unlink (tmpfile); 2087 2088 err = gpgme_op_keylist_start (tmpctx, NULL, 0); 2089 while (!err) 2090 { 2091 if ((err = gpgme_op_keylist_next (tmpctx, &key))) 2092 break; 2093 uid = key->uids; 2094 subkey = key->subkeys; 2095 more = 0; 2096 while (subkey) 2097 { 2098 shortid = subkey->keyid; 2099 len = mutt_strlen (subkey->keyid); 2100 if (len > 8) 2101 shortid += len - 8; 2102 tt = subkey->timestamp; 2103 strftime (date, sizeof (date), "%Y-%m-%d", localtime (&tt)); 2104 2105 if (!more) 2106 fprintf (*fp, "%s %5.5s %d/%8s %s %s\n", more ? "sub" : "pub", 2107 gpgme_pubkey_algo_name (subkey->pubkey_algo), subkey->length, 2108 shortid, date, uid->uid); 2109 else 2110 fprintf (*fp, "%s %5.5s %d/%8s %s\n", more ? "sub" : "pub", 2111 gpgme_pubkey_algo_name (subkey->pubkey_algo), subkey->length, 2112 shortid, date); 2113 subkey = subkey->next; 2114 more = 1; 2115 } 2116 gpgme_key_unref (key); 2117 } 2118 if (gpg_err_code (err) != GPG_ERR_EOF) 2119 { 2120 dprint (1, (debugfile, "Error listing keys\n")); 2121 goto err_fp; 2122 } 2123 2124 rc = 0; 2125 2126err_fp: 2127 if (rc) 2128 safe_fclose (fp); 2129err_tmpdir: 2130 if (dryrun) 2131 mutt_rmtree (tmpdir); 2132err_ctx: 2133 gpgme_release (tmpctx); 2134 2135 return rc; 2136} 2137 2138/* Check that 'b' is a complete line containing 'a' followed by either LF or CRLF. 2139 * 2140 * returns: 2141 * 0 if the is a match 2142 * -1 otherwise 2143 */ 2144static int line_compare(const char *a, size_t n, const char *b) 2145{ 2146 if (mutt_strncmp(a, b, n) == 0) 2147 { 2148 /* at this point we know that 'b' is at least 'n' chars long */ 2149 if (b[n] == '\n' || (b[n] == '\r' && b[n+1] == '\n')) 2150 return 0; 2151 } 2152 return -1; 2153} 2154 2155#define _LINE_COMPARE(_x,_y) !line_compare(_x, sizeof(_x)-1, _y) 2156#define MESSAGE(_y) _LINE_COMPARE("MESSAGE-----", _y) 2157#define SIGNED_MESSAGE(_y) _LINE_COMPARE("SIGNED MESSAGE-----", _y) 2158#define PUBLIC_KEY_BLOCK(_y) _LINE_COMPARE("PUBLIC KEY BLOCK-----", _y) 2159#define BEGIN_PGP_SIGNATURE(_y) _LINE_COMPARE("-----BEGIN PGP SIGNATURE-----", _y) 2160 2161/* 2162 * Implementation of `pgp_check_traditional'. 2163 */ 2164 2165static int pgp_check_traditional_one_body (FILE *fp, BODY *b, int tagged_only) 2166{ 2167 char tempfile[_POSIX_PATH_MAX]; 2168 char buf[HUGE_STRING]; 2169 FILE *tfp; 2170 2171 short sgn = 0; 2172 short enc = 0; 2173 2174 if (b->type != TYPETEXT) 2175 return 0; 2176 2177 if (tagged_only && !b->tagged) 2178 return 0; 2179 2180 mutt_mktemp (tempfile, sizeof (tempfile)); 2181 if (mutt_decode_save_attachment (fp, b, tempfile, 0, 0) != 0) 2182 { 2183 unlink (tempfile); 2184 return 0; 2185 } 2186 2187 if ((tfp = fopen (tempfile, "r")) == NULL) 2188 { 2189 unlink (tempfile); 2190 return 0; 2191 } 2192 2193 while (fgets (buf, sizeof (buf), tfp)) 2194 { 2195 if (!mutt_strncmp ("-----BEGIN PGP ", buf, 15)) 2196 { 2197 if (MESSAGE(buf + 15)) 2198 { 2199 enc = 1; 2200 break; 2201 } 2202 else if (SIGNED_MESSAGE(buf + 15)) 2203 { 2204 sgn = 1; 2205 break; 2206 } 2207 } 2208 } 2209 safe_fclose (&tfp); 2210 unlink (tempfile); 2211 2212 if (!enc && !sgn) 2213 return 0; 2214 2215 /* fix the content type */ 2216 2217 mutt_set_parameter ("format", "fixed", &b->parameter); 2218 mutt_set_parameter ("x-action", enc ? "pgp-encrypted" : "pgp-signed", 2219 &b->parameter); 2220 2221 return 1; 2222} 2223 2224int pgp_gpgme_check_traditional (FILE *fp, BODY *b, int tagged_only) 2225{ 2226 int rv = 0; 2227 int r; 2228 for (; b; b = b->next) 2229 { 2230 if (is_multipart (b)) 2231 rv = (pgp_gpgme_check_traditional (fp, b->parts, tagged_only) || rv); 2232 else if (b->type == TYPETEXT) 2233 { 2234 if ((r = mutt_is_application_pgp (b))) 2235 rv = (rv || r); 2236 else 2237 rv = (pgp_check_traditional_one_body (fp, b, tagged_only) || rv); 2238 } 2239 } 2240 return rv; 2241} 2242 2243void pgp_gpgme_invoke_import (const char *fname) 2244{ 2245 gpgme_data_t keydata; 2246 gpgme_error_t err; 2247 FILE* in; 2248 FILE* out; 2249 2250 if (!(in = safe_fopen (fname, "r"))) 2251 return; 2252 /* Note that the stream, "in", needs to be kept open while the keydata 2253 * is used. 2254 */ 2255 if ((err = gpgme_data_new_from_stream (&keydata, in)) != GPG_ERR_NO_ERROR) 2256 { 2257 safe_fclose (&in); 2258 mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err)); 2259 mutt_sleep (1); 2260 return; 2261 } 2262 2263 if (pgp_gpgme_extract_keys (keydata, &out, 0)) 2264 { 2265 mutt_error (_("Error extracting key data!\n")); 2266 mutt_sleep (1); 2267 } 2268 gpgme_data_release (keydata); 2269 safe_fclose (&in); 2270 safe_fclose (&out); 2271} 2272 2273 2274/* 2275 * Implementation of `application_handler'. 2276 */ 2277 2278/* 2279 Copy a clearsigned message, and strip the signature and PGP's 2280 dash-escaping. 2281 2282 XXX - charset handling: We assume that it is safe to do 2283 character set decoding first, dash decoding second here, while 2284 we do it the other way around in the main handler. 2285 2286 (Note that we aren't worse than Outlook & Cie in this, and also 2287 note that we can successfully handle anything produced by any 2288 existing versions of mutt.) */ 2289 2290static void copy_clearsigned (gpgme_data_t data, STATE *s, char *charset) 2291{ 2292 char buf[HUGE_STRING]; 2293 short complete, armor_header; 2294 FGETCONV *fc; 2295 char *fname; 2296 FILE *fp; 2297 2298 fname = data_object_to_tempfile (data, NULL, &fp); 2299 if (!fname) 2300 return; 2301 unlink (fname); 2302 FREE (&fname); 2303 2304 /* fromcode comes from the MIME Content-Type charset label. It might 2305 * be a wrong label, so we want the ability to do corrections via 2306 * charset-hooks. Therefore we set flags to MUTT_ICONV_HOOK_FROM. 2307 */ 2308 fc = fgetconv_open (fp, charset, Charset, MUTT_ICONV_HOOK_FROM); 2309 2310 for (complete = 1, armor_header = 1; 2311 fgetconvs (buf, sizeof (buf), fc) != NULL; 2312 complete = strchr (buf, '\n') != NULL) 2313 { 2314 if (!complete) 2315 { 2316 if (!armor_header) 2317 state_puts (buf, s); 2318 continue; 2319 } 2320 2321 if (BEGIN_PGP_SIGNATURE(buf)) 2322 break; 2323 2324 if (armor_header) 2325 { 2326 if (buf[0] == '\n') 2327 armor_header = 0; 2328 continue; 2329 } 2330 2331 if (s->prefix) 2332 state_puts (s->prefix, s); 2333 2334 if (buf[0] == '-' && buf[1] == ' ') 2335 state_puts (buf + 2, s); 2336 else 2337 state_puts (buf, s); 2338 } 2339 2340 fgetconv_close (&fc); 2341 safe_fclose (&fp); 2342} 2343 2344/* Support for classic_application/pgp */ 2345int pgp_gpgme_application_handler (BODY *m, STATE *s) 2346{ 2347 int needpass = -1, pgp_keyblock = 0; 2348 int clearsign = 0; 2349 long bytes; 2350 LOFF_T last_pos, offset; 2351 char buf[HUGE_STRING]; 2352 FILE *pgpout = NULL; 2353 2354 gpgme_error_t err = 0; 2355 gpgme_data_t armored_data = NULL; 2356 2357 short maybe_goodsig = 1; 2358 short have_any_sigs = 0; 2359 2360 char body_charset[STRING]; /* Only used for clearsigned messages. */ 2361 2362 dprint (2, (debugfile, "Entering pgp_application_pgp handler\n")); 2363 2364 /* For clearsigned messages we won't be able to get a character set 2365 but we know that this may only be text thus we assume Latin-1 2366 here. */ 2367 if (!mutt_get_body_charset (body_charset, sizeof (body_charset), m)) 2368 strfcpy (body_charset, "iso-8859-1", sizeof body_charset); 2369 2370 fseeko (s->fpin, m->offset, 0); 2371 last_pos = m->offset; 2372 2373 for (bytes = m->length; bytes > 0;) 2374 { 2375 if (fgets (buf, sizeof (buf), s->fpin) == NULL) 2376 break; 2377 2378 offset = ftello (s->fpin); 2379 bytes -= (offset - last_pos); /* don't rely on mutt_strlen(buf) */ 2380 last_pos = offset; 2381 2382 if (!mutt_strncmp ("-----BEGIN PGP ", buf, 15)) 2383 { 2384 clearsign = 0; 2385 2386 if (MESSAGE(buf + 15)) 2387 needpass = 1; 2388 else if (SIGNED_MESSAGE(buf + 15)) 2389 { 2390 clearsign = 1; 2391 needpass = 0; 2392 } 2393 else if (PUBLIC_KEY_BLOCK(buf + 15)) 2394 { 2395 needpass = 0; 2396 pgp_keyblock = 1; 2397 } 2398 else 2399 { 2400 /* XXX - we may wish to recode here */ 2401 if (s->prefix) 2402 state_puts (s->prefix, s); 2403 state_puts (buf, s); 2404 continue; 2405 } 2406 2407 have_any_sigs = (have_any_sigs 2408 || (clearsign && (s->flags & MUTT_VERIFY))); 2409 2410 /* Copy PGP material to an data container */ 2411 armored_data = file_to_data_object (s->fpin, m->offset, m->length); 2412 /* Invoke PGP if needed */ 2413 if (pgp_keyblock) 2414 { 2415 pgp_gpgme_extract_keys (armored_data, &pgpout, 1); 2416 } 2417 else if (!clearsign || (s->flags & MUTT_VERIFY)) 2418 { 2419 unsigned int sig_stat = 0; 2420 gpgme_data_t plaintext; 2421 gpgme_ctx_t ctx; 2422 2423 plaintext = create_gpgme_data (); 2424 ctx = create_gpgme_context (0); 2425 2426 if (clearsign) 2427 err = gpgme_op_verify (ctx, armored_data, NULL, plaintext); 2428 else 2429 { 2430 err = gpgme_op_decrypt_verify (ctx, armored_data, plaintext); 2431 if (gpg_err_code (err) == GPG_ERR_NO_DATA) 2432 { 2433 /* Decrypt verify can't handle signed only messages. */ 2434 err = (gpgme_data_seek (armored_data, 0, SEEK_SET) == -1) 2435 ? gpgme_error_from_errno (errno) : 0; 2436 /* Must release plaintext so that we supply an 2437 uninitialized object. */ 2438 gpgme_data_release (plaintext); 2439 plaintext = create_gpgme_data (); 2440 err = gpgme_op_verify (ctx, armored_data, 2441 NULL, plaintext); 2442 } 2443 } 2444 mutt_need_hard_redraw (); 2445 2446 if (err) 2447 { 2448 char errbuf[200]; 2449 2450 snprintf (errbuf, sizeof(errbuf)-1, 2451 _("Error: decryption/verification failed: %s\n"), 2452 gpgme_strerror (err)); 2453 state_puts (errbuf, s); 2454 } 2455 else 2456 { /* Decryption/Verification succeeded */ 2457 char *tmpfname; 2458 2459 { 2460 /* Check whether signatures have been verified. */ 2461 gpgme_verify_result_t verify_result; 2462 2463 verify_result = gpgme_op_verify_result (ctx); 2464 if (verify_result->signatures) 2465 sig_stat = 1; 2466 } 2467 2468 have_any_sigs = 0; 2469 maybe_goodsig = 0; 2470 if ((s->flags & MUTT_DISPLAY) && sig_stat) 2471 { 2472 int res, idx; 2473 int anybad = 0; 2474 2475 state_attach_puts (_("[-- Begin signature " 2476 "information --]\n"), s); 2477 have_any_sigs = 1; 2478 for(idx=0; 2479 (res = show_one_sig_status (ctx, idx, s)) != -1; 2480 idx++) 2481 { 2482 if (res == 1) 2483 anybad = 1; 2484 } 2485 if (!anybad && idx) 2486 maybe_goodsig = 1; 2487 2488 state_attach_puts (_("[-- End signature " 2489 "information --]\n\n"), s); 2490 } 2491 2492 tmpfname = data_object_to_tempfile (plaintext, NULL, &pgpout); 2493 if (!tmpfname) 2494 { 2495 pgpout = NULL; 2496 state_puts (_("Error: copy data failed\n"), s); 2497 } 2498 else 2499 { 2500 unlink (tmpfname); 2501 FREE (&tmpfname); 2502 } 2503 } 2504 gpgme_data_release (plaintext); 2505 gpgme_release (ctx); 2506 } 2507 2508 /* 2509 * Now, copy cleartext to the screen. NOTE - we expect that PGP 2510 * outputs utf-8 cleartext. This may not always be true, but it 2511 * seems to be a reasonable guess. 2512 */ 2513 2514 if(s->flags & MUTT_DISPLAY) 2515 { 2516 if (needpass) 2517 state_attach_puts (_("[-- BEGIN PGP MESSAGE --]\n\n"), s); 2518 else if (pgp_keyblock) 2519 state_attach_puts (_("[-- BEGIN PGP PUBLIC KEY BLOCK --]\n"), 2520 s); 2521 else 2522 state_attach_puts (_("[-- BEGIN PGP SIGNED MESSAGE --]\n\n"), 2523 s); 2524 } 2525 2526 if (clearsign) 2527 { 2528 copy_clearsigned (armored_data, s, body_charset); 2529 } 2530 else if (pgpout) 2531 { 2532 FGETCONV *fc; 2533 int c; 2534 rewind (pgpout); 2535 fc = fgetconv_open (pgpout, "utf-8", Charset, 0); 2536 while ((c = fgetconv (fc)) != EOF) 2537 { 2538 state_putc (c, s); 2539 if (c == '\n' && s->prefix) 2540 state_puts (s->prefix, s); 2541 } 2542 fgetconv_close (&fc); 2543 } 2544 2545 if (s->flags & MUTT_DISPLAY) 2546 { 2547 state_putc ('\n', s); 2548 if (needpass) 2549 state_attach_puts (_("[-- END PGP MESSAGE --]\n"), s); 2550 else if (pgp_keyblock) 2551 state_attach_puts (_("[-- END PGP PUBLIC KEY BLOCK --]\n"), s); 2552 else 2553 state_attach_puts (_("[-- END PGP SIGNED MESSAGE --]\n"), s); 2554 } 2555 2556 gpgme_data_release (armored_data); 2557 if (pgpout) 2558 { 2559 safe_fclose (&pgpout); 2560 } 2561 } 2562 else 2563 { 2564 /* A traditional PGP part may mix signed and unsigned content */ 2565 /* XXX - we may wish to recode here */ 2566 if (s->prefix) 2567 state_puts (s->prefix, s); 2568 state_puts (buf, s); 2569 } 2570 } 2571 2572 m->goodsig = (maybe_goodsig && have_any_sigs); 2573 2574 if (needpass == -1) 2575 { 2576 state_attach_puts (_("[-- Error: could not find beginning" 2577 " of PGP message! --]\n\n"), s); 2578 return 1; 2579 } 2580 dprint (2, (debugfile, "Leaving pgp_application_pgp handler\n")); 2581 2582 return err; 2583} 2584 2585/* 2586 * Implementation of `encrypted_handler'. 2587 */ 2588 2589/* MIME handler for pgp/mime encrypted messages. 2590 * This handler is passed the application/octet-stream directly. 2591 * The caller must propagate a->goodsig to its parent. 2592 */ 2593int pgp_gpgme_encrypted_handler (BODY *a, STATE *s) 2594{ 2595 char tempfile[_POSIX_PATH_MAX]; 2596 FILE *fpout; 2597 BODY *tattach; 2598 int is_signed; 2599 int rc = 0; 2600 2601 dprint (2, (debugfile, "Entering pgp_encrypted handler\n")); 2602 2603 mutt_mktemp (tempfile, sizeof (tempfile)); 2604 if (!(fpout = safe_fopen (tempfile, "w+"))) 2605 { 2606 if (s->flags & MUTT_DISPLAY) 2607 state_attach_puts (_("[-- Error: could not create temporary file! " 2608 "--]\n"), s); 2609 return -1; 2610 } 2611 2612 tattach = decrypt_part (a, s, fpout, 0, &is_signed); 2613 if (tattach) 2614 { 2615 tattach->goodsig = is_signed > 0; 2616 2617 if (s->flags & MUTT_DISPLAY) 2618 state_attach_puts (is_signed? 2619 _("[-- The following data is PGP/MIME signed and encrypted --]\n\n"): 2620 _("[-- The following data is PGP/MIME encrypted --]\n\n"), 2621 s); 2622 2623 { 2624 FILE *savefp = s->fpin; 2625 s->fpin = fpout; 2626 rc = mutt_body_handler (tattach, s); 2627 s->fpin = savefp; 2628 } 2629 2630 /* 2631 * if a multipart/signed is the _only_ sub-part of a 2632 * multipart/encrypted, cache signature verification 2633 * status. 2634 */ 2635 if (mutt_is_multipart_signed (tattach) && !tattach->next) 2636 a->goodsig |= tattach->goodsig; 2637 2638 if (s->flags & MUTT_DISPLAY) 2639 { 2640 state_puts ("\n", s); 2641 state_attach_puts (is_signed? 2642 _("[-- End of PGP/MIME signed and encrypted data --]\n"): 2643 _("[-- End of PGP/MIME encrypted data --]\n"), 2644 s); 2645 } 2646 2647 mutt_free_body (&tattach); 2648 mutt_message _("PGP message successfully decrypted."); 2649 } 2650 else 2651 { 2652 mutt_error _("Could not decrypt PGP message"); 2653 mutt_sleep (2); 2654 rc = -1; 2655 } 2656 2657 safe_fclose (&fpout); 2658 mutt_unlink(tempfile); 2659 dprint (2, (debugfile, "Leaving pgp_encrypted handler\n")); 2660 2661 return rc; 2662} 2663 2664/* Support for application/smime */ 2665int smime_gpgme_application_handler (BODY *a, STATE *s) 2666{ 2667 char tempfile[_POSIX_PATH_MAX]; 2668 FILE *fpout; 2669 BODY *tattach; 2670 int is_signed; 2671 int rc = 0; 2672 2673 dprint (2, (debugfile, "Entering smime_encrypted handler\n")); 2674 2675 a->warnsig = 0; 2676 mutt_mktemp (tempfile, sizeof (tempfile)); 2677 if (!(fpout = safe_fopen (tempfile, "w+"))) 2678 { 2679 if (s->flags & MUTT_DISPLAY) 2680 state_attach_puts (_("[-- Error: could not create temporary file! " 2681 "--]\n"), s); 2682 return -1; 2683 } 2684 2685 tattach = decrypt_part (a, s, fpout, 1, &is_signed); 2686 if (tattach) 2687 { 2688 tattach->goodsig = is_signed > 0; 2689 2690 if (s->flags & MUTT_DISPLAY) 2691 state_attach_puts (is_signed? 2692 _("[-- The following data is S/MIME signed --]\n\n"): 2693 _("[-- The following data is S/MIME encrypted --]\n\n"), 2694 s); 2695 2696 { 2697 FILE *savefp = s->fpin; 2698 s->fpin = fpout; 2699 rc = mutt_body_handler (tattach, s); 2700 s->fpin = savefp; 2701 } 2702 2703 /* 2704 * if a multipart/signed is the _only_ sub-part of a 2705 * multipart/encrypted, cache signature verification 2706 * status. 2707 */ 2708 if (mutt_is_multipart_signed (tattach) && !tattach->next) 2709 { 2710 if (!(a->goodsig = tattach->goodsig)) 2711 a->warnsig = tattach->warnsig; 2712 } 2713 else if (tattach->goodsig) 2714 { 2715 a->goodsig = 1; 2716 a->warnsig = tattach->warnsig; 2717 } 2718 2719 if (s->flags & MUTT_DISPLAY) 2720 { 2721 state_puts ("\n", s); 2722 state_attach_puts (is_signed? 2723 _("[-- End of S/MIME signed data --]\n"): 2724 _("[-- End of S/MIME encrypted data --]\n"), 2725 s); 2726 } 2727 2728 mutt_free_body (&tattach); 2729 } 2730 2731 safe_fclose (&fpout); 2732 mutt_unlink(tempfile); 2733 dprint (2, (debugfile, "Leaving smime_encrypted handler\n")); 2734 2735 return rc; 2736} 2737 2738 2739/* 2740 * Format an entry on the CRYPT key selection menu. 2741 * 2742 * %n number 2743 * %k key id %K key id of the principal key 2744 * %u user id 2745 * %a algorithm %A algorithm of the princ. key 2746 * %l length %L length of the princ. key 2747 * %f flags %F flags of the princ. key 2748 * %c capabilities %C capabilities of the princ. key 2749 * %t trust/validity of the key-uid association 2750 * %p protocol 2751 * %[...] date of key using strftime(3) 2752 */ 2753 2754static const char *crypt_entry_fmt (char *dest, 2755 size_t destlen, 2756 size_t col, 2757 int cols, 2758 char op, 2759 const char *src, 2760 const char *prefix, 2761 const char *ifstring, 2762 const char *elsestring, 2763 unsigned long data, 2764 format_flag flags) 2765{ 2766 char fmt[16]; 2767 crypt_entry_t *entry; 2768 crypt_key_t *key; 2769 int kflags = 0; 2770 int optional = (flags & MUTT_FORMAT_OPTIONAL); 2771 const char *s = NULL; 2772 unsigned long val; 2773 2774 entry = (crypt_entry_t *) data; 2775 key = entry->key; 2776 2777/* if (isupper ((unsigned char) op)) */ 2778/* key = pkey; */ 2779 2780 kflags = (key->flags /*| (pkey->flags & KEYFLAG_RESTRICTIONS) 2781 | uid->flags*/); 2782 2783 switch (ascii_tolower (op)) 2784 { 2785 case '[': 2786 { 2787 const char *cp; 2788 char buf2[SHORT_STRING], *p; 2789 int do_locales; 2790 struct tm *tm; 2791 size_t len; 2792 2793 p = dest; 2794 2795 cp = src; 2796 if (*cp == '!') 2797 { 2798 do_locales = 0; 2799 cp++; 2800 } 2801 else 2802 do_locales = 1; 2803 2804 len = destlen - 1; 2805 while (len > 0 && *cp != ']') 2806 { 2807 if (*cp == '%') 2808 { 2809 cp++; 2810 if (len >= 2) 2811 { 2812 *p++ = '%'; 2813 *p++ = *cp; 2814 len -= 2; 2815 } 2816 else 2817 break; /* not enough space */ 2818 cp++; 2819 } 2820 else 2821 { 2822 *p++ = *cp++; 2823 len--; 2824 } 2825 } 2826 *p = 0; 2827 2828 { 2829 time_t tt = 0; 2830 2831 if (key->kobj->subkeys && (key->kobj->subkeys->timestamp > 0)) 2832 tt = key->kobj->subkeys->timestamp; 2833 2834 tm = localtime (&tt); 2835 } 2836 2837 if (!do_locales) 2838 setlocale (LC_TIME, "C"); 2839 strftime (buf2, sizeof (buf2), dest, tm); 2840 if (!do_locales) 2841 setlocale (LC_TIME, ""); 2842 2843 snprintf (fmt, sizeof (fmt), "%%%ss", prefix); 2844 snprintf (dest, destlen, fmt, buf2); 2845 if (len > 0) 2846 src = cp + 1; 2847 } 2848 break; 2849 case 'n': 2850 if (!optional) 2851 { 2852 snprintf (fmt, sizeof (fmt), "%%%sd", prefix); 2853 snprintf (dest, destlen, fmt, entry->num); 2854 } 2855 break; 2856 case 'k': 2857 if (!optional) 2858 { 2859 /* fixme: we need a way to distinguish between main and subkeys. 2860 Store the idx in entry? */ 2861 snprintf (fmt, sizeof (fmt), "%%%ss", prefix); 2862 snprintf (dest, destlen, fmt, crypt_keyid (key)); 2863 } 2864 break; 2865 case 'u': 2866 if (!optional) 2867 { 2868 snprintf (fmt, sizeof (fmt), "%%%ss", prefix); 2869 snprintf (dest, destlen, fmt, key->uid); 2870 } 2871 break; 2872 case 'a': 2873 if (!optional) 2874 { 2875 snprintf (fmt, sizeof (fmt), "%%%s.3s", prefix); 2876 if (key->kobj->subkeys) 2877 s = gpgme_pubkey_algo_name (key->kobj->subkeys->pubkey_algo); 2878 else 2879 s = "?"; 2880 snprintf (dest, destlen, fmt, s); 2881 } 2882 break; 2883 case 'l': 2884 if (!optional) 2885 { 2886 snprintf (fmt, sizeof (fmt), "%%%slu", prefix); 2887 if (key->kobj->subkeys) 2888 val = key->kobj->subkeys->length; 2889 else 2890 val = 0; 2891 snprintf (dest, destlen, fmt, val); 2892 } 2893 break; 2894 case 'f': 2895 if (!optional) 2896 { 2897 snprintf (fmt, sizeof (fmt), "%%%sc", prefix); 2898 snprintf (dest, destlen, fmt, crypt_flags (kflags)); 2899 } 2900 else if (!(kflags & (KEYFLAG_RESTRICTIONS))) 2901 optional = 0; 2902 break; 2903 case 'c': 2904 if (!optional) 2905 { 2906 snprintf (fmt, sizeof (fmt), "%%%ss", prefix); 2907 snprintf (dest, destlen, fmt, crypt_key_abilities (kflags)); 2908 } 2909 else if (!(kflags & (KEYFLAG_ABILITIES))) 2910 optional = 0; 2911 break; 2912 case 't': 2913 if ((kflags & KEYFLAG_ISX509)) 2914 s = "x"; 2915 else 2916 { 2917 switch (key->validity) 2918 { 2919 case GPGME_VALIDITY_UNDEFINED: 2920 s = "q"; 2921 break; 2922 case GPGME_VALIDITY_NEVER: 2923 s = "n"; 2924 break; 2925 case GPGME_VALIDITY_MARGINAL: 2926 s = "m"; 2927 break; 2928 case GPGME_VALIDITY_FULL: 2929 s = "f"; 2930 break; 2931 case GPGME_VALIDITY_ULTIMATE: 2932 s = "u"; 2933 break; 2934 case GPGME_VALIDITY_UNKNOWN: 2935 default: 2936 s = "?"; 2937 break; 2938 } 2939 } 2940 snprintf (fmt, sizeof (fmt), "%%%sc", prefix); 2941 snprintf (dest, destlen, fmt, s? *s: 'B'); 2942 break; 2943 case 'p': 2944 snprintf (fmt, sizeof (fmt), "%%%ss", prefix); 2945 snprintf (dest, destlen, fmt, 2946 gpgme_get_protocol_name (key->kobj->protocol)); 2947 break; 2948 2949 default: 2950 *dest = '\0'; 2951 } 2952 2953 if (optional) 2954 mutt_FormatString (dest, destlen, col, cols, ifstring, mutt_attach_fmt, data, 0); 2955 else if (flags & MUTT_FORMAT_OPTIONAL) 2956 mutt_FormatString (dest, destlen, col, cols, elsestring, mutt_attach_fmt, data, 0); 2957 return (src); 2958} 2959 2960/* Used by the display function to format a line. */ 2961static void crypt_entry (char *s, size_t l, MUTTMENU * menu, int num) 2962{ 2963 crypt_key_t **key_table = (crypt_key_t **) menu->data; 2964 crypt_entry_t entry; 2965 2966 entry.key = key_table[num]; 2967 entry.num = num + 1; 2968 2969 mutt_FormatString (s, l, 0, MuttIndexWindow->cols, NONULL (PgpEntryFormat), crypt_entry_fmt, 2970 (unsigned long) &entry, MUTT_FORMAT_ARROWCURSOR); 2971} 2972 2973/* Compare two addresses and the keyid to be used for sorting. */ 2974static int _crypt_compare_address (const void *a, const void *b) 2975{ 2976 crypt_key_t **s = (crypt_key_t **) a; 2977 crypt_key_t **t = (crypt_key_t **) b; 2978 int r; 2979 2980 if ((r = mutt_strcasecmp ((*s)->uid, (*t)->uid))) 2981 return r > 0; 2982 else 2983 return mutt_strcasecmp (crypt_fpr_or_lkeyid (*s), crypt_fpr_or_lkeyid (*t)) > 0; 2984} 2985 2986static int crypt_compare_address (const void *a, const void *b) 2987{ 2988 return ((PgpSortKeys & SORT_REVERSE) ? !_crypt_compare_address (a, b) 2989 : _crypt_compare_address (a, b)); 2990} 2991 2992 2993/* Compare two key IDs and the addresses to be used for sorting. */ 2994static int _crypt_compare_keyid (const void *a, const void *b) 2995{ 2996 crypt_key_t **s = (crypt_key_t **) a; 2997 crypt_key_t **t = (crypt_key_t **) b; 2998 int r; 2999 3000 if ((r = mutt_strcasecmp (crypt_fpr_or_lkeyid (*s), crypt_fpr_or_lkeyid (*t)))) 3001 return r > 0; 3002 else 3003 return mutt_strcasecmp ((*s)->uid, (*t)->uid) > 0; 3004} 3005 3006static int crypt_compare_keyid (const void *a, const void *b) 3007{ 3008 return ((PgpSortKeys & SORT_REVERSE) ? !_crypt_compare_keyid (a, b) 3009 : _crypt_compare_keyid (a, b)); 3010} 3011 3012/* Compare 2 creation dates and the addresses. For sorting. */ 3013static int _crypt_compare_date (const void *a, const void *b) 3014{ 3015 crypt_key_t **s = (crypt_key_t **) a; 3016 crypt_key_t **t = (crypt_key_t **) b; 3017 unsigned long ts = 0, tt = 0; 3018 3019 if ((*s)->kobj->subkeys && ((*s)->kobj->subkeys->timestamp > 0)) 3020 ts = (*s)->kobj->subkeys->timestamp; 3021 if ((*t)->kobj->subkeys && ((*t)->kobj->subkeys->timestamp > 0)) 3022 tt = (*t)->kobj->subkeys->timestamp; 3023 3024 if (ts > tt) 3025 return 1; 3026 if (ts < tt) 3027 return 0; 3028 3029 return mutt_strcasecmp ((*s)->uid, (*t)->uid) > 0; 3030} 3031 3032static int crypt_compare_date (const void *a, const void *b) 3033{ 3034 return ((PgpSortKeys & SORT_REVERSE) ? !_crypt_compare_date (a, b) 3035 : _crypt_compare_date (a, b)); 3036} 3037 3038/* Compare two trust values, the key length, the creation dates. the 3039 addresses and the key IDs. For sorting. */ 3040static int _crypt_compare_trust (const void *a, const void *b) 3041{ 3042 crypt_key_t **s = (crypt_key_t **) a; 3043 crypt_key_t **t = (crypt_key_t **) b; 3044 unsigned long ts = 0, tt = 0; 3045 int r; 3046 3047 if ((r = (((*s)->flags & (KEYFLAG_RESTRICTIONS)) 3048 - ((*t)->flags & (KEYFLAG_RESTRICTIONS))))) 3049 return r > 0; 3050 3051 ts = (*s)->validity; 3052 tt = (*t)->validity; 3053 if ((r = (tt - ts))) 3054 return r < 0; 3055 3056 if ((*s)->kobj->subkeys) 3057 ts = (*s)->kobj->subkeys->length; 3058 if ((*t)->kobj->subkeys) 3059 tt = (*t)->kobj->subkeys->length; 3060 if (ts != tt) 3061 return ts > tt; 3062 3063 if ((*s)->kobj->subkeys && ((*s)->kobj->subkeys->timestamp > 0)) 3064 ts = (*s)->kobj->subkeys->timestamp; 3065 if ((*t)->kobj->subkeys && ((*t)->kobj->subkeys->timestamp > 0)) 3066 tt = (*t)->kobj->subkeys->timestamp; 3067 if (ts > tt) 3068 return 1; 3069 if (ts < tt) 3070 return 0; 3071 3072 if ((r = mutt_strcasecmp ((*s)->uid, (*t)->uid))) 3073 return r > 0; 3074 return (mutt_strcasecmp (crypt_fpr_or_lkeyid ((*s)), crypt_fpr_or_lkeyid ((*t)))) > 0; 3075} 3076 3077static int crypt_compare_trust (const void *a, const void *b) 3078{ 3079 return ((PgpSortKeys & SORT_REVERSE) ? !_crypt_compare_trust (a, b) 3080 : _crypt_compare_trust (a, b)); 3081} 3082 3083/* Print the X.500 Distinguished Name part KEY from the array of parts 3084 DN to FP. */ 3085static int 3086print_dn_part (FILE *fp, struct dn_array_s *dn, const char *key) 3087{ 3088 int any = 0; 3089 3090 for (; dn->key; dn++) 3091 { 3092 if (!strcmp (dn->key, key)) 3093 { 3094 if (any) 3095 fputs (" + ", fp); 3096 print_utf8 (fp, dn->value, strlen (dn->value)); 3097 any = 1; 3098 } 3099 } 3100 return any; 3101} 3102 3103/* Print all parts of a DN in a standard sequence. */ 3104static void 3105print_dn_parts (FILE *fp, struct dn_array_s *dn) 3106{ 3107 static const char * const stdpart[] = { 3108 "CN", "OU", "O", "STREET", "L", "ST", "C", NULL 3109 }; 3110 int any=0, any2=0, i; 3111 3112 for (i=0; stdpart[i]; i++) 3113 { 3114 if (any) 3115 fputs (", ", fp); 3116 any = print_dn_part (fp, dn, stdpart[i]); 3117 } 3118 /* now print the rest without any specific ordering */ 3119 for (; dn->key; dn++) 3120 { 3121 for (i=0; stdpart[i]; i++) 3122 { 3123 if (!strcmp (dn->key, stdpart[i])) 3124 break; 3125 } 3126 if (!stdpart[i]) 3127 { 3128 if (any) 3129 fputs (", ", fp); 3130 if (!any2) 3131 fputs ("(", fp); 3132 any = print_dn_part (fp, dn, dn->key); 3133 any2 = 1; 3134 } 3135 } 3136 if (any2) 3137 fputs (")", fp); 3138} 3139 3140 3141/* Parse an RDN; this is a helper to parse_dn(). */ 3142static const unsigned char * 3143parse_dn_part (struct dn_array_s *array, const unsigned char *string) 3144{ 3145 const unsigned char *s, *s1; 3146 size_t n; 3147 unsigned char *p; 3148 3149 /* parse attributeType */ 3150 for (s = string+1; *s && *s != '='; s++) 3151 ; 3152 if (!*s) 3153 return NULL; /* error */ 3154 n = s - string; 3155 if (!n) 3156 return NULL; /* empty key */ 3157 array->key = safe_malloc (n+1); 3158 p = (unsigned char *)array->key; 3159 memcpy (p, string, n); /* fixme: trim trailing spaces */ 3160 p[n] = 0; 3161 string = s + 1; 3162 3163 if (*string == '#') 3164 { /* hexstring */ 3165 string++; 3166 for (s=string; hexdigitp (s); s++) 3167 s++; 3168 n = s - string; 3169 if (!n || (n & 1)) 3170 return NULL; /* empty or odd number of digits */ 3171 n /= 2; 3172 p = safe_malloc (n+1); 3173 array->value = (char*)p; 3174 for (s1=string; n; s1 += 2, n--) 3175 *p++ = xtoi_2 (s1); 3176 *p = 0; 3177 } 3178 else 3179 { /* regular v3 quoted string */ 3180 for (n=0, s=string; *s; s++) 3181 { 3182 if (*s == '\\') 3183 { /* pair */ 3184 s++; 3185 if (*s == ',' || *s == '=' || *s == '+' 3186 || *s == '<' || *s == '>' || *s == '#' || *s == ';' 3187 || *s == '\\' || *s == '\"' || *s == ' ') 3188 n++; 3189 else if (hexdigitp (s) && hexdigitp (s+1)) 3190 { 3191 s++; 3192 n++; 3193 } 3194 else 3195 return NULL; /* invalid escape sequence */ 3196 } 3197 else if (*s == '\"') 3198 return NULL; /* invalid encoding */ 3199 else if (*s == ',' || *s == '=' || *s == '+' 3200 || *s == '<' || *s == '>' || *s == '#' || *s == ';' ) 3201 break; 3202 else 3203 n++; 3204 } 3205 3206 p = safe_malloc (n+1); 3207 array->value = (char*)p; 3208 for (s=string; n; s++, n--) 3209 { 3210 if (*s == '\\') 3211 { 3212 s++; 3213 if (hexdigitp (s)) 3214 { 3215 *p++ = xtoi_2 (s); 3216 s++; 3217 } 3218 else 3219 *p++ = *s; 3220 } 3221 else 3222 *p++ = *s; 3223 } 3224 *p = 0; 3225 } 3226 return s; 3227} 3228 3229 3230/* Parse a DN and return an array-ized one. This is not a validating 3231 parser and it does not support any old-stylish syntax; gpgme is 3232 expected to return only rfc2253 compatible strings. */ 3233static struct dn_array_s * 3234parse_dn (const unsigned char *string) 3235{ 3236 struct dn_array_s *array; 3237 size_t arrayidx, arraysize; 3238 int i; 3239 3240 arraysize = 7; /* C,ST,L,O,OU,CN,email */ 3241 array = safe_malloc ((arraysize+1) * sizeof *array); 3242 arrayidx = 0; 3243 while (*string) 3244 { 3245 while (*string == ' ') 3246 string++; 3247 if (!*string) 3248 break; /* ready */ 3249 if (arrayidx >= arraysize) 3250 { /* mutt lacks a real safe_realoc - so we need to copy */ 3251 struct dn_array_s *a2; 3252 3253 arraysize += 5; 3254 a2 = safe_malloc ((arraysize+1) * sizeof *array); 3255 for (i=0; i < arrayidx; i++) 3256 { 3257 a2[i].key = array[i].key; 3258 a2[i].value = array[i].value; 3259 } 3260 FREE (&array); 3261 array = a2; 3262 } 3263 array[arrayidx].key = NULL; 3264 array[arrayidx].value = NULL; 3265 string = parse_dn_part (array+arrayidx, string); 3266 arrayidx++; 3267 if (!string) 3268 goto failure; 3269 while (*string == ' ') 3270 string++; 3271 if (*string && *string != ',' && *string != ';' && *string != '+') 3272 goto failure; /* invalid delimiter */ 3273 if (*string) 3274 string++; 3275 } 3276 array[arrayidx].key = NULL; 3277 array[arrayidx].value = NULL; 3278 return array; 3279 3280 failure: 3281 for (i=0; i < arrayidx; i++) 3282 { 3283 FREE (&array[i].key); 3284 FREE (&array[i].value); 3285 } 3286 FREE (&array); 3287 return NULL; 3288} 3289 3290 3291/* Print a nice representation of the USERID and make sure it is 3292 displayed in a proper way, which does mean to reorder some parts 3293 for S/MIME's DNs. USERID is a string as returned by the gpgme key 3294 functions. It is utf-8 encoded. */ 3295static void 3296parse_and_print_user_id (FILE *fp, const char *userid) 3297{ 3298 const char *s; 3299 int i; 3300 3301 if (*userid == '<') 3302 { 3303 s = strchr (userid+1, '>'); 3304 if (s) 3305 print_utf8 (fp, userid+1, s-userid-1); 3306 } 3307 else if (*userid == '(') 3308 fputs (_("[Can't display this user ID (unknown encoding)]"), fp); 3309 else if (!digit_or_letter ((const unsigned char *)userid)) 3310 fputs (_("[Can't display this user ID (invalid encoding)]"), fp); 3311 else 3312 { 3313 struct dn_array_s *dn = parse_dn ((const unsigned char *)userid); 3314 if (!dn) 3315 fputs (_("[Can't display this user ID (invalid DN)]"), fp); 3316 else 3317 { 3318 print_dn_parts (fp, dn); 3319 for (i=0; dn[i].key; i++) 3320 { 3321 FREE (&dn[i].key); 3322 FREE (&dn[i].value); 3323 } 3324 FREE (&dn); 3325 } 3326 } 3327} 3328 3329typedef enum 3330 { 3331 KEY_CAP_CAN_ENCRYPT, 3332 KEY_CAP_CAN_SIGN, 3333 KEY_CAP_CAN_CERTIFY 3334 } 3335key_cap_t; 3336 3337static unsigned int 3338key_check_cap (gpgme_key_t key, key_cap_t cap) 3339{ 3340 gpgme_subkey_t subkey = NULL; 3341 unsigned int ret = 0; 3342 3343 switch (cap) 3344 { 3345 case KEY_CAP_CAN_ENCRYPT: 3346 if (! (ret = key->can_encrypt)) 3347 for (subkey = key->subkeys; subkey; subkey = subkey->next) 3348 if ((ret = subkey->can_encrypt)) 3349 break; 3350 break; 3351 case KEY_CAP_CAN_SIGN: 3352 if (! (ret = key->can_sign)) 3353 for (subkey = key->subkeys; subkey; subkey = subkey->next) 3354 if ((ret = subkey->can_sign)) 3355 break; 3356 break; 3357 case KEY_CAP_CAN_CERTIFY: 3358 if (! (ret = key->can_certify)) 3359 for (subkey = key->subkeys; subkey; subkey = subkey->next) 3360 if ((ret = subkey->can_certify)) 3361 break; 3362 break; 3363 } 3364 3365 return ret; 3366} 3367 3368 3369/* Print verbose information about a key or certificate to FP. */ 3370static void print_key_info (gpgme_key_t key, FILE *fp) 3371{ 3372 int idx; 3373 const char *s = NULL, *s2 = NULL; 3374 time_t tt = 0; 3375 struct tm *tm; 3376 char shortbuf[SHORT_STRING]; 3377 unsigned long aval = 0; 3378 const char *delim; 3379 int is_pgp = 0; 3380 int i; 3381 gpgme_user_id_t uid = NULL; 3382 3383 is_pgp = key->protocol == GPGME_PROTOCOL_OpenPGP; 3384 3385 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next) 3386 { 3387 if (uid->revoked) 3388 continue; 3389 3390 s = uid->uid; 3391 /* L10N: 3392 Fill dots to make the DOTFILL entries the same length. 3393 In English, msgid "Fingerprint: " is the longest entry for this menu. 3394 Your language may vary. */ 3395 fputs (idx ? _(" aka ......: ") :_("Name ......: "), fp); 3396 if (uid->invalid) 3397 { 3398 fputs (_("[Invalid]"), fp); 3399 putc (' ', fp); 3400 } 3401 if (is_pgp) 3402 print_utf8 (fp, s, strlen(s)); 3403 else 3404 parse_and_print_user_id (fp, s); 3405 putc ('\n', fp); 3406 } 3407 3408 if (key->subkeys && (key->subkeys->timestamp > 0)) 3409 { 3410 tt = key->subkeys->timestamp; 3411 3412 tm = localtime (&tt); 3413#ifdef HAVE_LANGINFO_D_T_FMT 3414 strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm); 3415#else 3416 strftime (shortbuf, sizeof shortbuf, "%c", tm); 3417#endif 3418 /* L10N: DOTFILL */ 3419 fprintf (fp, _("Valid From : %s\n"), shortbuf); 3420 } 3421 3422 if (key->subkeys && (key->subkeys->expires > 0)) 3423 { 3424 tt = key->subkeys->expires; 3425 3426 tm = localtime (&tt); 3427#ifdef HAVE_LANGINFO_D_T_FMT 3428 strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm); 3429#else 3430 strftime (shortbuf, sizeof shortbuf, "%c", tm); 3431#endif 3432 /* L10N: DOTFILL */ 3433 fprintf (fp, _("Valid To ..: %s\n"), shortbuf); 3434 } 3435 3436 if (key->subkeys) 3437 s = gpgme_pubkey_algo_name (key->subkeys->pubkey_algo); 3438 else 3439 s = "?"; 3440 3441 s2 = is_pgp ? "PGP" : "X.509"; 3442 3443 if (key->subkeys) 3444 aval = key->subkeys->length; 3445 3446 /* L10N: DOTFILL */ 3447 fprintf (fp, _("Key Type ..: %s, %lu bit %s\n"), s2, aval, s); 3448 3449 /* L10N: DOTFILL */ 3450 fprintf (fp, _("Key Usage .: ")); 3451 delim = ""; 3452 3453 if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT)) 3454 { 3455 fprintf (fp, "%s%s", delim, _("encryption")); 3456 delim = _(", "); 3457 } 3458 if (key_check_cap (key, KEY_CAP_CAN_SIGN)) 3459 { 3460 fprintf (fp, "%s%s", delim, _("signing")); 3461 delim = _(", "); 3462 } 3463 if (key_check_cap (key, KEY_CAP_CAN_CERTIFY)) 3464 { 3465 fprintf (fp, "%s%s", delim, _("certification")); 3466 delim = _(", "); 3467 } 3468 putc ('\n', fp); 3469 3470 if (key->subkeys) 3471 { 3472 s = key->subkeys->fpr; 3473 /* L10N: DOTFILL */ 3474 fputs (_("Fingerprint: "), fp); 3475 if (is_pgp && strlen (s) == 40) 3476 { 3477 for (i=0; *s && s[1] && s[2] && s[3] && s[4]; s += 4, i++) 3478 { 3479 putc (*s, fp); 3480 putc (s[1], fp); 3481 putc (s[2], fp); 3482 putc (s[3], fp); 3483 putc (is_pgp? ' ':':', fp); 3484 if (is_pgp && i == 4) 3485 putc (' ', fp); 3486 } 3487 } 3488 else 3489 { 3490 for (i=0; *s && s[1] && s[2]; s += 2, i++) 3491 { 3492 putc (*s, fp); 3493 putc (s[1], fp); 3494 putc (is_pgp? ' ':':', fp); 3495 if (is_pgp && i == 7) 3496 putc (' ', fp); 3497 } 3498 } 3499 fprintf (fp, "%s\n", s); 3500 } 3501 3502 if (key->issuer_serial) 3503 { 3504 s = key->issuer_serial; 3505 if (s) 3506 /* L10N: DOTFILL */ 3507 fprintf (fp, _("Serial-No .: 0x%s\n"), s); 3508 } 3509 3510 if (key->issuer_name) 3511 { 3512 s = key->issuer_name; 3513 if (s) 3514 { 3515 /* L10N: DOTFILL */ 3516 fprintf (fp, _("Issued By .: ")); 3517 parse_and_print_user_id (fp, s); 3518 putc ('\n', fp); 3519 } 3520 } 3521 3522 /* For PGP we list all subkeys. */ 3523 if (is_pgp) 3524 { 3525 gpgme_subkey_t subkey = NULL; 3526 3527 for (idx = 1, subkey = key->subkeys; subkey; 3528 idx++, subkey = subkey->next) 3529 { 3530 s = subkey->keyid; 3531 3532 putc ('\n', fp); 3533 if ( strlen (s) == 16) 3534 s += 8; /* display only the short keyID */ 3535 /* L10N: DOTFILL */ 3536 fprintf (fp, _("Subkey ....: 0x%s"), s); 3537 if (subkey->revoked) 3538 { 3539 putc (' ', fp); 3540 fputs (_("[Revoked]"), fp); 3541 } 3542 if (subkey->invalid) 3543 { 3544 putc (' ', fp); 3545 fputs (_("[Invalid]"), fp); 3546 } 3547 if (subkey->expired) 3548 { 3549 putc (' ', fp); 3550 fputs (_("[Expired]"), fp); 3551 } 3552 if (subkey->disabled) 3553 { 3554 putc (' ', fp); 3555 fputs (_("[Disabled]"), fp); 3556 } 3557 putc ('\n', fp); 3558 3559 if (subkey->timestamp > 0) 3560 { 3561 tt = subkey->timestamp; 3562 3563 tm = localtime (&tt); 3564#ifdef HAVE_LANGINFO_D_T_FMT 3565 strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm); 3566#else 3567 strftime (shortbuf, sizeof shortbuf, "%c", tm); 3568#endif 3569 /* L10N: DOTFILL */ 3570 fprintf (fp, _("Valid From : %s\n"), shortbuf); 3571 } 3572 3573 if (subkey->expires > 0) 3574 { 3575 tt = subkey->expires; 3576 3577 tm = localtime (&tt); 3578#ifdef HAVE_LANGINFO_D_T_FMT 3579 strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm); 3580#else 3581 strftime (shortbuf, sizeof shortbuf, "%c", tm); 3582#endif 3583 /* L10N: DOTFILL */ 3584 fprintf (fp, _("Valid To ..: %s\n"), shortbuf); 3585 } 3586 3587 if (subkey) 3588 s = gpgme_pubkey_algo_name (subkey->pubkey_algo); 3589 else 3590 s = "?"; 3591 3592 if (subkey) 3593 aval = subkey->length; 3594 else 3595 aval = 0; 3596 3597 /* L10N: DOTFILL */ 3598 fprintf (fp, _("Key Type ..: %s, %lu bit %s\n"), "PGP", aval, s); 3599 3600 /* L10N: DOTFILL */ 3601 fprintf (fp, _("Key Usage .: ")); 3602 delim = ""; 3603 3604 if (subkey->can_encrypt) 3605 { 3606 fprintf (fp, "%s%s", delim, _("encryption")); 3607 delim = _(", "); 3608 } 3609 if (subkey->can_sign) 3610 { 3611 fprintf (fp, "%s%s", delim, _("signing")); 3612 delim = _(", "); 3613 } 3614 if (subkey->can_certify) 3615 { 3616 fprintf (fp, "%s%s", delim, _("certification")); 3617 delim = _(", "); 3618 } 3619 putc ('\n', fp); 3620 } 3621 } 3622} 3623 3624 3625/* Show detailed information about the selected key */ 3626static void 3627verify_key (crypt_key_t *key) 3628{ 3629 FILE *fp; 3630 char cmd[LONG_STRING], tempfile[_POSIX_PATH_MAX]; 3631 const char *s; 3632 gpgme_ctx_t listctx = NULL; 3633 gpgme_error_t err; 3634 gpgme_key_t k = NULL; 3635 int maxdepth = 100; 3636 3637 mutt_mktemp (tempfile, sizeof (tempfile)); 3638 if (!(fp = safe_fopen (tempfile, "w"))) 3639 { 3640 mutt_perror _("Can't create temporary file"); 3641 return; 3642 } 3643 mutt_message _("Collecting data..."); 3644 3645 print_key_info (key->kobj, fp); 3646 3647 err = gpgme_new (&listctx); 3648 if (err) 3649 { 3650 fprintf (fp, "Internal error: can't create gpgme context: %s\n", 3651 gpgme_strerror (err)); 3652 goto leave; 3653 } 3654 if ((key->flags & KEYFLAG_ISX509)) 3655 gpgme_set_protocol (listctx, GPGME_PROTOCOL_CMS); 3656 3657 k = key->kobj; 3658 gpgme_key_ref (k); 3659 while ((s = k->chain_id) && k->subkeys && strcmp (s, k->subkeys->fpr) ) 3660 { 3661 putc ('\n', fp); 3662 err = gpgme_op_keylist_start (listctx, s, 0); 3663 gpgme_key_unref (k); 3664 k = NULL; 3665 if (!err) 3666 err = gpgme_op_keylist_next (listctx, &k); 3667 if (err) 3668 { 3669 fprintf (fp, _("Error finding issuer key: %s\n"), 3670 gpgme_strerror (err)); 3671 goto leave; 3672 } 3673 gpgme_op_keylist_end (listctx); 3674 3675 print_key_info (k, fp); 3676 if (!--maxdepth) 3677 { 3678 putc ('\n', fp); 3679 fputs (_("Error: certification chain too long - stopping here\n"), 3680 fp); 3681 break; 3682 } 3683 } 3684 3685 leave: 3686 gpgme_key_unref (k); 3687 gpgme_release (listctx); 3688 safe_fclose (&fp); 3689 mutt_clear_error (); 3690 snprintf (cmd, sizeof (cmd), _("Key ID: 0x%s"), crypt_keyid (key)); 3691 mutt_do_pager (cmd, tempfile, 0, NULL); 3692} 3693 3694/* 3695 * Implementation of `findkeys'. 3696 */ 3697 3698 3699/* Convert LIST into a pattern string suitable to be passed to GPGME. 3700 We need to convert spaces in an item into a '+' and '%' into 3701 "%25". */ 3702static char *list_to_pattern (LIST *list) 3703{ 3704 LIST *l; 3705 char *pattern, *p; 3706 const char *s; 3707 size_t n; 3708 3709 n = 0; 3710 for(l=list; l; l = l->next) 3711 { 3712 for(s = l->data; *s; s++) 3713 { 3714 if (*s == '%' || *s == '+') 3715 n += 2; 3716 n++; 3717 } 3718 n++; /* delimiter or end of string */ 3719 } 3720 n++; /* make sure to allocate at least one byte */ 3721 pattern = p = safe_calloc (1,n); 3722 for(l=list; l; l = l->next) 3723 { 3724 s = l->data; 3725 if (*s) 3726 { 3727 if (l != list) 3728 *p++ = ' '; 3729 for(s = l->data; *s; s++) 3730 { 3731 if (*s == '%') 3732 { 3733 *p++ = '%'; 3734 *p++ = '2'; 3735 *p++ = '5'; 3736 } 3737 else if (*s == '+') 3738 { 3739 *p++ = '%'; 3740 *p++ = '2'; 3741 *p++ = 'B'; 3742 } 3743 else if (*s == ' ') 3744 *p++ = '+'; 3745 else 3746 *p++ = *s; 3747 } 3748 } 3749 } 3750 *p = 0; 3751 return pattern; 3752} 3753 3754/* Return a list of keys which are candidates for the selection. 3755 Select by looking at the HINTS list. */ 3756static crypt_key_t *get_candidates (LIST * hints, unsigned int app, int secret) 3757{ 3758 crypt_key_t *db, *k, **kend; 3759 char *pattern; 3760 gpgme_error_t err; 3761 gpgme_ctx_t ctx; 3762 gpgme_key_t key; 3763 int idx; 3764 gpgme_user_id_t uid = NULL; 3765 3766 pattern = list_to_pattern (hints); 3767 if (!pattern) 3768 return NULL; 3769 3770 err = gpgme_new (&ctx); 3771 if (err) 3772 { 3773 mutt_error (_("gpgme_new failed: %s"), gpgme_strerror (err)); 3774 FREE (&pattern); 3775 return NULL; 3776 } 3777 3778 db = NULL; 3779 kend = &db; 3780 3781 if ((app & APPLICATION_PGP)) 3782 { 3783 /* Its all a mess. That old GPGME expects different things 3784 depending on the protocol. For gpg we don' t need percent 3785 escaped pappert but simple strings passed in an array to the 3786 keylist_ext_start function. */ 3787 LIST *l; 3788 size_t n; 3789 char **patarr; 3790 3791 for(l=hints, n=0; l; l = l->next) 3792 { 3793 if (l->data && *l->data) 3794 n++; 3795 } 3796 if (!n) 3797 goto no_pgphints; 3798 3799 patarr = safe_calloc (n+1, sizeof *patarr); 3800 for(l=hints, n=0; l; l = l->next) 3801 { 3802 if (l->data && *l->data) 3803 patarr[n++] = safe_strdup (l->data); 3804 } 3805 patarr[n] = NULL; 3806 err = gpgme_op_keylist_ext_start (ctx, (const char**)patarr, secret, 0); 3807 for (n=0; patarr[n]; n++) 3808 FREE (&patarr[n]); 3809 FREE (&patarr); 3810 if (err) 3811 { 3812 mutt_error (_("gpgme_op_keylist_start failed: %s"), 3813 gpgme_strerror (err)); 3814 gpgme_release (ctx); 3815 FREE (&pattern); 3816 return NULL; 3817 } 3818 3819 while (!(err = gpgme_op_keylist_next (ctx, &key)) ) 3820 { 3821 unsigned int flags = 0; 3822 3823 if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT)) 3824 flags |= KEYFLAG_CANENCRYPT; 3825 if (key_check_cap (key, KEY_CAP_CAN_SIGN)) 3826 flags |= KEYFLAG_CANSIGN; 3827 3828 if (key->revoked) 3829 flags |= KEYFLAG_REVOKED; 3830 if (key->expired) 3831 flags |= KEYFLAG_EXPIRED; 3832 if (key->disabled) 3833 flags |= KEYFLAG_DISABLED; 3834 3835#if 0 /* DISABLED code */ 3836 if (!flags) 3837 { 3838 /* Bug in gpg. Capabilities are not listed for secret 3839 keys. Try to deduce them from the algorithm. */ 3840 3841 switch (key->subkeys[0].pubkey_algo) 3842 { 3843 case GPGME_PK_RSA: 3844 flags |= KEYFLAG_CANENCRYPT; 3845 flags |= KEYFLAG_CANSIGN; 3846 break; 3847 case GPGME_PK_ELG_E: 3848 flags |= KEYFLAG_CANENCRYPT; 3849 break; 3850 case GPGME_PK_DSA: 3851 flags |= KEYFLAG_CANSIGN; 3852 break; 3853 } 3854 } 3855#endif /* DISABLED code */ 3856 3857 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next) 3858 { 3859 k = safe_calloc (1, sizeof *k); 3860 k->kobj = key; 3861 gpgme_key_ref (k->kobj); 3862 k->idx = idx; 3863 k->uid = uid->uid; 3864 k->flags = flags; 3865 if (uid->revoked) 3866 k->flags |= KEYFLAG_REVOKED; 3867 k->validity = uid->validity; 3868 *kend = k; 3869 kend = &k->next; 3870 } 3871 gpgme_key_unref (key); 3872 } 3873 if (gpg_err_code (err) != GPG_ERR_EOF) 3874 mutt_error (_("gpgme_op_keylist_next failed: %s"), gpgme_strerror (err)); 3875 gpgme_op_keylist_end (ctx); 3876 no_pgphints: 3877 ; 3878 } 3879 3880 if ((app & APPLICATION_SMIME)) 3881 { 3882 /* and now look for x509 certificates */ 3883 gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); 3884 err = gpgme_op_keylist_start (ctx, pattern, 0); 3885 if (err) 3886 { 3887 mutt_error (_("gpgme_op_keylist_start failed: %s"), 3888 gpgme_strerror (err)); 3889 gpgme_release (ctx); 3890 FREE (&pattern); 3891 return NULL; 3892 } 3893 3894 while (!(err = gpgme_op_keylist_next (ctx, &key)) ) 3895 { 3896 unsigned int flags = KEYFLAG_ISX509; 3897 3898 if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT)) 3899 flags |= KEYFLAG_CANENCRYPT; 3900 if (key_check_cap (key, KEY_CAP_CAN_SIGN)) 3901 flags |= KEYFLAG_CANSIGN; 3902 3903 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next) 3904 { 3905 k = safe_calloc (1, sizeof *k); 3906 k->kobj = key; 3907 gpgme_key_ref (k->kobj); 3908 k->idx = idx; 3909 k->uid = uid->uid; 3910 k->flags = flags; 3911 k->validity = uid->validity; 3912 *kend = k; 3913 kend = &k->next; 3914 } 3915 gpgme_key_unref (key); 3916 } 3917 if (gpg_err_code (err) != GPG_ERR_EOF) 3918 mutt_error (_("gpgme_op_keylist_next failed: %s"), gpgme_strerror (err)); 3919 gpgme_op_keylist_end (ctx); 3920 } 3921 3922 gpgme_release (ctx); 3923 FREE (&pattern); 3924 return db; 3925} 3926 3927/* Add the string STR to the list HINTS. This list is later used to 3928 match addresses. */ 3929static LIST *crypt_add_string_to_hints (LIST *hints, const char *str) 3930{ 3931 char *scratch; 3932 char *t; 3933 3934 if ((scratch = safe_strdup (str)) == NULL) 3935 return hints; 3936 3937 for (t = strtok (scratch, " ,.:\"()<>\n"); t; 3938 t = strtok (NULL, " ,.:\"()<>\n")) 3939 { 3940 if (strlen (t) > 3) 3941 hints = mutt_add_list (hints, t); 3942 } 3943 3944 FREE (&scratch); 3945 return hints; 3946} 3947 3948/* Display a menu to select a key from the array KEYS. FORCED_VALID 3949 will be set to true on return if the user did override the the 3950 key's validity. */ 3951static crypt_key_t *crypt_select_key (crypt_key_t *keys, 3952 ADDRESS * p, const char *s, 3953 unsigned int app, int *forced_valid) 3954{ 3955 int keymax; 3956 crypt_key_t **key_table; 3957 MUTTMENU *menu; 3958 int i, done = 0; 3959 char helpstr[LONG_STRING], buf[LONG_STRING]; 3960 crypt_key_t *k; 3961 int (*f) (const void *, const void *); 3962 int menu_to_use = 0; 3963 int unusable = 0; 3964 3965 *forced_valid = 0; 3966 3967 /* build the key table */ 3968 keymax = i = 0; 3969 key_table = NULL; 3970 for (k = keys; k; k = k->next) 3971 { 3972 if (!option (OPTPGPSHOWUNUSABLE) && (k->flags & KEYFLAG_CANTUSE)) 3973 { 3974 unusable = 1; 3975 continue; 3976 } 3977 3978 if (i == keymax) 3979 { 3980 keymax += 20; 3981 safe_realloc (&key_table, sizeof (crypt_key_t*)*keymax); 3982 } 3983 3984 key_table[i++] = k; 3985 } 3986 3987 if (!i && unusable) 3988 { 3989 mutt_error _("All matching keys are marked expired/revoked."); 3990 mutt_sleep (1); 3991 return NULL; 3992 } 3993 3994 switch (PgpSortKeys & SORT_MASK) 3995 { 3996 case SORT_DATE: 3997 f = crypt_compare_date; 3998 break; 3999 case SORT_KEYID: 4000 f = crypt_compare_keyid; 4001 break; 4002 case SORT_ADDRESS: 4003 f = crypt_compare_address; 4004 break; 4005 case SORT_TRUST: 4006 default: 4007 f = crypt_compare_trust; 4008 break; 4009 } 4010 qsort (key_table, i, sizeof (crypt_key_t*), f); 4011 4012 if (app & APPLICATION_PGP) 4013 menu_to_use = MENU_KEY_SELECT_PGP; 4014 else if (app & APPLICATION_SMIME) 4015 menu_to_use = MENU_KEY_SELECT_SMIME; 4016 4017 helpstr[0] = 0; 4018 mutt_make_help (buf, sizeof (buf), _("Exit "), menu_to_use, OP_EXIT); 4019 strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ 4020 mutt_make_help (buf, sizeof (buf), _("Select "), menu_to_use, 4021 OP_GENERIC_SELECT_ENTRY); 4022 strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ 4023 mutt_make_help (buf, sizeof (buf), _("Check key "), 4024 menu_to_use, OP_VERIFY_KEY); 4025 strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ 4026 mutt_make_help (buf, sizeof (buf), _("Help"), menu_to_use, OP_HELP); 4027 strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ 4028 4029 menu = mutt_new_menu (menu_to_use); 4030 menu->max = i; 4031 menu->make_entry = crypt_entry; 4032 menu->help = helpstr; 4033 menu->data = key_table; 4034 4035 { 4036 const char *ts; 4037 4038 if ((app & APPLICATION_PGP) && (app & APPLICATION_SMIME)) 4039 ts = _("PGP and S/MIME keys matching"); 4040 else if ((app & APPLICATION_PGP)) 4041 ts = _("PGP keys matching"); 4042 else if ((app & APPLICATION_SMIME)) 4043 ts = _("S/MIME keys matching"); 4044 else 4045 ts = _("keys matching"); 4046 4047 if (p) 4048 /* L10N: 4049 %1$s is one of the previous four entries. 4050 %2$s is an address. 4051 e.g. "S/MIME keys matching <me@mutt.org>." */ 4052 snprintf (buf, sizeof (buf), _("%s <%s>."), ts, p->mailbox); 4053 else 4054 /* L10N: 4055 e.g. 'S/MIME keys matching "Michael Elkins".' */ 4056 snprintf (buf, sizeof (buf), _("%s \"%s\"."), ts, s); 4057 menu->title = buf; 4058 } 4059 4060 mutt_clear_error (); 4061 k = NULL; 4062 while (!done) 4063 { 4064 *forced_valid = 0; 4065 switch (mutt_menuLoop (menu)) 4066 { 4067 case OP_VERIFY_KEY: 4068 verify_key (key_table[menu->current]); 4069 menu->redraw = REDRAW_FULL; 4070 break; 4071 4072 case OP_VIEW_ID: 4073 mutt_message ("%s", key_table[menu->current]->uid); 4074 break; 4075 4076 case OP_GENERIC_SELECT_ENTRY: 4077 /* FIXME make error reporting more verbose - this should be 4078 easy because gpgme provides more information */ 4079 if (option (OPTPGPCHECKTRUST)) 4080 { 4081 if (!crypt_key_is_valid (key_table[menu->current])) 4082 { 4083 mutt_error _("This key can't be used: " 4084 "expired/disabled/revoked."); 4085 break; 4086 } 4087 } 4088 4089 if (option (OPTPGPCHECKTRUST) && 4090 (!crypt_id_is_valid (key_table[menu->current]) 4091 || !crypt_id_is_strong (key_table[menu->current]))) 4092 { 4093 const char *warn_s; 4094 char buff[LONG_STRING]; 4095 4096 if (key_table[menu->current]->flags & KEYFLAG_CANTUSE) 4097 warn_s = N_("ID is expired/disabled/revoked."); 4098 else 4099 { 4100 warn_s = "??"; 4101 switch (key_table[menu->current]->validity) 4102 { 4103 case GPGME_VALIDITY_UNKNOWN: 4104 case GPGME_VALIDITY_UNDEFINED: 4105 warn_s = N_("ID has undefined validity."); 4106 break; 4107 case GPGME_VALIDITY_NEVER: 4108 warn_s = N_("ID is not valid."); 4109 break; 4110 case GPGME_VALIDITY_MARGINAL: 4111 warn_s = N_("ID is only marginally valid."); 4112 break; 4113 case GPGME_VALIDITY_FULL: 4114 case GPGME_VALIDITY_ULTIMATE: 4115 break; 4116 } 4117 } 4118 4119 snprintf (buff, sizeof (buff), 4120 _("%s Do you really want to use the key?"), 4121 _(warn_s)); 4122 4123 if (mutt_yesorno (buff, 0) != 1) 4124 { 4125 mutt_clear_error (); 4126 break; 4127 } 4128 *forced_valid = 1; 4129 } 4130 4131 k = crypt_copy_key (key_table[menu->current]); 4132 done = 1; 4133 break; 4134 4135 case OP_EXIT: 4136 k = NULL; 4137 done = 1; 4138 break; 4139 } 4140 } 4141 4142 mutt_menuDestroy (&menu); 4143 FREE (&key_table); 4144 4145 set_option (OPTNEEDREDRAW); 4146 4147 return k; 4148} 4149 4150static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities, 4151 unsigned int app, int *forced_valid, 4152 int oppenc_mode) 4153{ 4154 ADDRESS *r, *p; 4155 LIST *hints = NULL; 4156 4157 int weak = 0; 4158 int invalid = 0; 4159 int addr_match = 0; 4160 int multi = 0; 4161 int this_key_has_strong; 4162 int this_key_has_addr_match; 4163 int this_key_has_weak; 4164 int this_key_has_invalid; 4165 int match; 4166 4167 crypt_key_t *keys, *k; 4168 crypt_key_t *the_strong_valid_key = NULL; 4169 crypt_key_t *a_valid_addrmatch_key = NULL; 4170 crypt_key_t *matches = NULL; 4171 crypt_key_t **matches_endp = &matches; 4172 4173 *forced_valid = 0; 4174 4175 if (a && a->mailbox) 4176 hints = crypt_add_string_to_hints (hints, a->mailbox); 4177 if (a && a->personal) 4178 hints = crypt_add_string_to_hints (hints, a->personal); 4179 4180 if (! oppenc_mode ) 4181 mutt_message (_("Looking for keys matching \"%s\"..."), a->mailbox); 4182 keys = get_candidates (hints, app, (abilities & KEYFLAG_CANSIGN) ); 4183 4184 mutt_free_list (&hints); 4185 4186 if (!keys) 4187 return NULL; 4188 4189 dprint (5, (debugfile, "crypt_getkeybyaddr: looking for %s <%s>.", 4190 a->personal, a->mailbox)); 4191 4192 for (k = keys; k; k = k->next) 4193 { 4194 dprint (5, (debugfile, " looking at key: %s `%.15s'\n", 4195 crypt_keyid (k), k->uid)); 4196 4197 if (abilities && !(k->flags & abilities)) 4198 { 4199 dprint (5, (debugfile, " insufficient abilities: Has %x, want %x\n", 4200 k->flags, abilities)); 4201 continue; 4202 } 4203 4204 this_key_has_weak = 0; /* weak but valid match */ 4205 this_key_has_invalid = 0; /* invalid match */ 4206 this_key_has_strong = 0; /* strong and valid match */ 4207 this_key_has_addr_match = 0; 4208 match = 0; /* any match */ 4209 4210 r = rfc822_parse_adrlist (NULL, k->uid); 4211 for (p = r; p; p = p->next) 4212 { 4213 int validity = crypt_id_matches_addr (a, p, k); 4214 4215 if (validity & CRYPT_KV_MATCH) /* something matches */ 4216 { 4217 match = 1; 4218 4219 if (validity & CRYPT_KV_VALID) 4220 { 4221 if (validity & CRYPT_KV_ADDR) 4222 { 4223 if (validity & CRYPT_KV_STRONGID) 4224 { 4225 if (the_strong_valid_key 4226 && the_strong_valid_key->kobj != k->kobj) 4227 multi = 1; 4228 this_key_has_strong = 1; 4229 } 4230 else 4231 this_key_has_addr_match = 1; 4232 } 4233 else 4234 this_key_has_weak = 1; 4235 } 4236 else 4237 this_key_has_invalid = 1; 4238 } 4239 } 4240 rfc822_free_address (&r); 4241 4242 if (match) 4243 { 4244 crypt_key_t *tmp; 4245 4246 *matches_endp = tmp = crypt_copy_key (k); 4247 matches_endp = &tmp->next; 4248 4249 if (this_key_has_strong) 4250 the_strong_valid_key = tmp; 4251 else if (this_key_has_addr_match) 4252 { 4253 addr_match = 1; 4254 a_valid_addrmatch_key = tmp; 4255 } 4256 else if (this_key_has_invalid) 4257 invalid = 1; 4258 else if (this_key_has_weak) 4259 weak = 1; 4260 } 4261 } 4262 4263 crypt_free_key (&keys); 4264 4265 if (matches) 4266 { 4267 if (oppenc_mode) 4268 { 4269 if (the_strong_valid_key) 4270 k = crypt_copy_key (the_strong_valid_key); 4271 else if (a_valid_addrmatch_key) 4272 k = crypt_copy_key (a_valid_addrmatch_key); 4273 else 4274 k = NULL; 4275 } 4276 else if (the_strong_valid_key && !multi && !weak && !addr_match 4277 && !(invalid && option (OPTPGPSHOWUNUSABLE))) 4278 { 4279 /* 4280 * There was precisely one strong match on a valid ID, there 4281 * were no valid keys with weak matches, and we aren't 4282 * interested in seeing invalid keys. 4283 * 4284 * Proceed without asking the user. 4285 */ 4286 k = crypt_copy_key (the_strong_valid_key); 4287 } 4288 else 4289 { 4290 /* 4291 * Else: Ask the user. 4292 */ 4293 k = crypt_select_key (matches, a, NULL, app, forced_valid); 4294 } 4295 4296 crypt_free_key (&matches); 4297 } 4298 else 4299 k = NULL; 4300 4301 return k; 4302} 4303 4304 4305static crypt_key_t *crypt_getkeybystr (char *p, short abilities, 4306 unsigned int app, int *forced_valid) 4307{ 4308 LIST *hints = NULL; 4309 crypt_key_t *keys; 4310 crypt_key_t *matches = NULL; 4311 crypt_key_t **matches_endp = &matches; 4312 crypt_key_t *k; 4313 const char *ps, *pl, *pfcopy, *phint; 4314 4315 mutt_message (_("Looking for keys matching \"%s\"..."), p); 4316 4317 *forced_valid = 0; 4318 4319 pfcopy = crypt_get_fingerprint_or_id (p, &phint, &pl, &ps); 4320 hints = crypt_add_string_to_hints (hints, phint); 4321 keys = get_candidates (hints, app, (abilities & KEYFLAG_CANSIGN)); 4322 mutt_free_list (&hints); 4323 4324 if (!keys) 4325 { 4326 FREE (&pfcopy); 4327 return NULL; 4328 } 4329 4330 for (k = keys; k; k = k->next) 4331 { 4332 if (abilities && !(k->flags & abilities)) 4333 continue; 4334 4335 dprint (5, (debugfile, "crypt_getkeybystr: matching \"%s\" against " 4336 "key %s, \"%s\": ", p, crypt_long_keyid (k), k->uid)); 4337 4338 if (!*p 4339 || (pfcopy && mutt_strcasecmp (pfcopy, crypt_fpr (k)) == 0) 4340 || (pl && mutt_strcasecmp (pl, crypt_long_keyid (k)) == 0) 4341 || (ps && mutt_strcasecmp (ps, crypt_short_keyid (k)) == 0) 4342 || mutt_stristr (k->uid, p)) 4343 { 4344 crypt_key_t *tmp; 4345 4346 dprint (5, (debugfile, "match.\n")); 4347 4348 *matches_endp = tmp = crypt_copy_key (k); 4349 matches_endp = &tmp->next; 4350 } 4351 } 4352 4353 FREE (&pfcopy); 4354 crypt_free_key (&keys); 4355 4356 if (matches) 4357 { 4358 k = crypt_select_key (matches, NULL, p, app, forced_valid); 4359 crypt_free_key (&matches); 4360 return k; 4361 } 4362 4363 return NULL; 4364} 4365 4366/* Display TAG as a prompt to ask for a key. If WHATFOR is not null 4367 use it as default and store it under that label as the next 4368 default. ABILITIES describe the required key abilities (sign, 4369 encrypt) and APP the type of the requested key; ether S/MIME or 4370 PGP. Return a copy of the key or NULL if not found. */ 4371static crypt_key_t *crypt_ask_for_key (char *tag, 4372 char *whatfor, 4373 short abilities, 4374 unsigned int app, 4375 int *forced_valid) 4376{ 4377 crypt_key_t *key; 4378 char resp[SHORT_STRING]; 4379 struct crypt_cache *l = NULL; 4380 int dummy; 4381 4382 if (!forced_valid) 4383 forced_valid = &dummy; 4384 4385 mutt_clear_error (); 4386 4387 *forced_valid = 0; 4388 resp[0] = 0; 4389 if (whatfor) 4390 { 4391 4392 for (l = id_defaults; l; l = l->next) 4393 if (!mutt_strcasecmp (whatfor, l->what)) 4394 { 4395 strfcpy (resp, NONULL (l->dflt), sizeof (resp)); 4396 break; 4397 } 4398 } 4399 4400 4401 for (;;) 4402 { 4403 resp[0] = 0; 4404 if (mutt_get_field (tag, resp, sizeof (resp), MUTT_CLEAR) != 0) 4405 return NULL; 4406 4407 if (whatfor) 4408 { 4409 if (l) 4410 mutt_str_replace (&l->dflt, resp); 4411 else 4412 { 4413 l = safe_malloc (sizeof (struct crypt_cache)); 4414 l->next = id_defaults; 4415 id_defaults = l; 4416 l->what = safe_strdup (whatfor); 4417 l->dflt = safe_strdup (resp); 4418 } 4419 } 4420 4421 if ((key = crypt_getkeybystr (resp, abilities, app, forced_valid))) 4422 return key; 4423 4424 BEEP (); 4425 } 4426 /* not reached */ 4427} 4428 4429/* This routine attempts to find the keyids of the recipients of a 4430 message. It returns NULL if any of the keys can not be found. 4431 If oppenc_mode is true, only keys that can be determined without 4432 prompting will be used. */ 4433static char *find_keys (ADDRESS *adrlist, unsigned int app, int oppenc_mode) 4434{ 4435 LIST *crypt_hook_list, *crypt_hook = NULL; 4436 char *crypt_hook_val = NULL; 4437 const char *keyID = NULL; 4438 char *keylist = NULL, *t; 4439 size_t keylist_size = 0; 4440 size_t keylist_used = 0; 4441 ADDRESS *addr = NULL; 4442 ADDRESS *p, *q; 4443 crypt_key_t *k_info; 4444 const char *fqdn = mutt_fqdn (1); 4445 char buf[LONG_STRING]; 4446 int forced_valid; 4447 int r; 4448 int key_selected; 4449 4450#if 0 4451 *r_application = APPLICATION_PGP|APPLICATION_SMIME; 4452#endif 4453 4454 for (p = adrlist; p ; p = p->next) 4455 { 4456 key_selected = 0; 4457 crypt_hook_list = crypt_hook = mutt_crypt_hook (p); 4458 do 4459 { 4460 q = p; 4461 forced_valid = 0; 4462 k_info = NULL; 4463 4464 if (crypt_hook != NULL) 4465 { 4466 crypt_hook_val = crypt_hook->data; 4467 r = MUTT_YES; 4468 if (! oppenc_mode && option(OPTCRYPTCONFIRMHOOK)) 4469 { 4470 snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), 4471 crypt_hook_val, p->mailbox); 4472 r = mutt_yesorno (buf, MUTT_YES); 4473 } 4474 if (r == MUTT_YES) 4475 { 4476 if (crypt_is_numerical_keyid (crypt_hook_val)) 4477 { 4478 keyID = crypt_hook_val; 4479 if (strncmp (keyID, "0x", 2) == 0) 4480 keyID += 2; 4481 goto bypass_selection; /* you don't see this. */ 4482 } 4483 4484 /* check for e-mail address */ 4485 if ((t = strchr (crypt_hook_val, '@')) && 4486 (addr = rfc822_parse_adrlist (NULL, crypt_hook_val))) 4487 { 4488 if (fqdn) 4489 rfc822_qualify (addr, fqdn); 4490 q = addr; 4491 } 4492 else if (! oppenc_mode) 4493 { 4494#if 0 4495 k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT, 4496 *r_application, &forced_valid); 4497#else 4498 k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT, 4499 app, &forced_valid); 4500#endif 4501 } 4502 } 4503 else if (r == MUTT_NO) 4504 { 4505 if (key_selected || (crypt_hook->next != NULL)) 4506 { 4507 crypt_hook = crypt_hook->next; 4508 continue; 4509 } 4510 } 4511 else if (r == -1) 4512 { 4513 FREE (&keylist); 4514 rfc822_free_address (&addr); 4515 mutt_free_list (&crypt_hook_list); 4516 return NULL; 4517 } 4518 } 4519 4520 if (k_info == NULL) 4521 { 4522 k_info = crypt_getkeybyaddr (q, KEYFLAG_CANENCRYPT, 4523 app, &forced_valid, oppenc_mode); 4524 } 4525 4526 if ((k_info == NULL) && (! oppenc_mode)) 4527 { 4528 snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox); 4529 4530 k_info = crypt_ask_for_key (buf, q->mailbox, 4531 KEYFLAG_CANENCRYPT, 4532#if 0 4533 *r_application, 4534#else 4535 app, 4536#endif 4537 &forced_valid); 4538 } 4539 4540 if (k_info == NULL) 4541 { 4542 FREE (&keylist); 4543 rfc822_free_address (&addr); 4544 mutt_free_list (&crypt_hook_list); 4545 return NULL; 4546 } 4547 4548 4549 keyID = crypt_fpr_or_lkeyid (k_info); 4550 4551#if 0 4552 if (k_info->flags & KEYFLAG_ISX509) 4553 *r_application &= ~APPLICATION_PGP; 4554 if (!(k_info->flags & KEYFLAG_ISX509)) 4555 *r_application &= ~APPLICATION_SMIME; 4556#endif 4557 4558 bypass_selection: 4559 keylist_size += mutt_strlen (keyID) + 4 + 1; 4560 safe_realloc (&keylist, keylist_size); 4561 sprintf (keylist + keylist_used, "%s0x%s%s", /* __SPRINTF_CHECKED__ */ 4562 keylist_used ? " " : "", keyID, 4563 forced_valid? "!":""); 4564 keylist_used = mutt_strlen (keylist); 4565 4566 key_selected = 1; 4567 4568 crypt_free_key (&k_info); 4569 rfc822_free_address (&addr); 4570 4571 if (crypt_hook != NULL) 4572 crypt_hook = crypt_hook->next; 4573 4574 } while (crypt_hook != NULL); 4575 4576 mutt_free_list (&crypt_hook_list); 4577 } 4578 return (keylist); 4579} 4580 4581char *pgp_gpgme_findkeys (ADDRESS *adrlist, int oppenc_mode) 4582{ 4583 return find_keys (adrlist, APPLICATION_PGP, oppenc_mode); 4584} 4585 4586char *smime_gpgme_findkeys (ADDRESS *adrlist, int oppenc_mode) 4587{ 4588 return find_keys (adrlist, APPLICATION_SMIME, oppenc_mode); 4589} 4590 4591#ifdef HAVE_GPGME_OP_EXPORT_KEYS 4592BODY *pgp_gpgme_make_key_attachment (char *tempf) 4593{ 4594 crypt_key_t *key = NULL; 4595 gpgme_ctx_t context = NULL; 4596 gpgme_key_t export_keys[2]; 4597 gpgme_data_t keydata = NULL; 4598 gpgme_error_t err; 4599 BODY *att = NULL; 4600 char buff[LONG_STRING]; 4601 struct stat sb; 4602 4603 unset_option (OPTPGPCHECKTRUST); 4604 4605 key = crypt_ask_for_key (_("Please enter the key ID: "), NULL, 0, 4606 APPLICATION_PGP, NULL); 4607 if (!key) 4608 goto bail; 4609 export_keys[0] = key->kobj; 4610 export_keys[1] = NULL; 4611 4612 context = create_gpgme_context (0); 4613 gpgme_set_armor (context, 1); 4614 keydata = create_gpgme_data (); 4615 err = gpgme_op_export_keys (context, export_keys, 0, keydata); 4616 if (err != GPG_ERR_NO_ERROR) 4617 { 4618 mutt_error (_("Error exporting key: %s\n"), gpgme_strerror (err)); 4619 mutt_sleep (1); 4620 goto bail; 4621 } 4622 4623 tempf = data_object_to_tempfile (keydata, tempf, NULL); 4624 if (!tempf) 4625 goto bail; 4626 4627 att = mutt_new_body (); 4628 /* tempf is a newly allocated string, so this is correct: */ 4629 att->filename = tempf; 4630 att->unlink = 1; 4631 att->use_disp = 0; 4632 att->type = TYPEAPPLICATION; 4633 att->subtype = safe_strdup ("pgp-keys"); 4634 /* L10N: 4635 MIME description for exported (attached) keys. 4636 You can translate this entry to a non-ASCII string (it will be encoded), 4637 but it may be safer to keep it untranslated. */ 4638 snprintf (buff, sizeof (buff), _("PGP Key 0x%s."), crypt_keyid (key)); 4639 att->description = safe_strdup (buff); 4640 mutt_update_encoding (att); 4641 4642 stat (tempf, &sb); 4643 att->length = sb.st_size; 4644 4645bail: 4646 crypt_free_key (&key); 4647 gpgme_data_release (keydata); 4648 gpgme_release (context); 4649 4650 return att; 4651} 4652#endif 4653 4654/* 4655 * Implementation of `init'. 4656 */ 4657 4658/* This function contains common code needed to be executed for both the pgp 4659 * and smime support of gpgme. */ 4660static void init_common(void) 4661{ 4662 /* this initialization should only run one time, but it may be called by 4663 * either pgp_gpgme_init or smime_gpgme_init */ 4664 static bool has_run = 0; 4665 if (!has_run) { 4666 gpgme_check_version(NULL); 4667 gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); 4668#ifdef ENABLE_NLS 4669 gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); 4670#endif 4671 has_run = 1; /* note use of 1 here is intentional to avoid requiring "true" 4672 to be defined. see #3657 */ 4673 } 4674} 4675 4676static void init_pgp (void) 4677{ 4678 if (gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP) != GPG_ERR_NO_ERROR) 4679 { 4680 mutt_error (_("GPGME: OpenPGP protocol not available")); 4681 } 4682} 4683 4684static void init_smime (void) 4685{ 4686 if (gpgme_engine_check_version (GPGME_PROTOCOL_CMS) != GPG_ERR_NO_ERROR) 4687 { 4688 mutt_error (_("GPGME: CMS protocol not available")); 4689 } 4690} 4691 4692void pgp_gpgme_init (void) 4693{ 4694 init_common (); 4695 init_pgp (); 4696} 4697 4698void smime_gpgme_init (void) 4699{ 4700 init_common (); 4701 init_smime (); 4702} 4703 4704static int gpgme_send_menu (HEADER *msg, int *redraw, int is_smime) 4705{ 4706 crypt_key_t *p; 4707 char input_signas[SHORT_STRING]; 4708 char *prompt, *letters, *choices; 4709 int choice; 4710 4711 if (is_smime) 4712 msg->security |= APPLICATION_SMIME; 4713 else 4714 msg->security |= APPLICATION_PGP; 4715 4716 /* 4717 * Opportunistic encrypt is controlling encryption. 4718 * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different 4719 * letter choices for those. 4720 */ 4721 if (option (OPTCRYPTOPPORTUNISTICENCRYPT) && (msg->security & OPPENCRYPT)) 4722 { 4723 if (is_smime) 4724 { 4725 prompt = _("S/MIME (s)ign, sign (a)s, (p)gp, (c)lear, or (o)ppenc mode off? "); 4726 /* L10N: The 'f' is from "forget it", an old undocumented synonym of 4727 'clear'. Please use a corresponding letter in your language. 4728 Alternatively, you may duplicate the letter 'c' is translated to. 4729 This comment also applies to the five following letter sequences. */ 4730 letters = _("sapfco"); 4731 choices = "SapFCo"; 4732 } 4733 else 4734 { 4735 prompt = _("PGP (s)ign, sign (a)s, s/(m)ime, (c)lear, or (o)ppenc mode off? "); 4736 letters = _("samfco"); 4737 choices = "SamFCo"; 4738 } 4739 } 4740 /* 4741 * Opportunistic encryption option is set, but is toggled off 4742 * for this message. 4743 */ 4744 else if (option (OPTCRYPTOPPORTUNISTICENCRYPT)) 4745 { 4746 if (is_smime) 4747 { 4748 prompt = _("S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (p)gp, (c)lear, or (o)ppenc mode? "); 4749 letters = _("esabpfco"); 4750 choices = "esabpfcO"; 4751 } 4752 else 4753 { 4754 prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime, (c)lear, or (o)ppenc mode? "); 4755 letters = _("esabmfco"); 4756 choices = "esabmfcO"; 4757 } 4758 } 4759 /* 4760 * Opportunistic encryption is unset 4761 */ 4762 else 4763 { 4764 if (is_smime) 4765 { 4766 prompt = _("S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (p)gp or (c)lear? "); 4767 letters = _("esabpfc"); 4768 choices = "esabpfc"; 4769 } 4770 else 4771 { 4772 prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime or (c)lear? "); 4773 letters = _("esabmfc"); 4774 choices = "esabmfc"; 4775 } 4776 } 4777 4778 choice = mutt_multi_choice (prompt, letters); 4779 if (choice > 0) 4780 { 4781 switch (choices[choice - 1]) 4782 { 4783 case 'e': /* (e)ncrypt */ 4784 msg->security |= ENCRYPT; 4785 msg->security &= ~SIGN; 4786 break; 4787 4788 case 's': /* (s)ign */ 4789 msg->security &= ~ENCRYPT; 4790 msg->security |= SIGN; 4791 break; 4792 4793 case 'S': /* (s)ign in oppenc mode */ 4794 msg->security |= SIGN; 4795 break; 4796 4797 case 'a': /* sign (a)s */ 4798 if ((p = crypt_ask_for_key (_("Sign as: "), NULL, KEYFLAG_CANSIGN, 4799 is_smime? APPLICATION_SMIME:APPLICATION_PGP, 4800 NULL))) 4801 { 4802 snprintf (input_signas, sizeof (input_signas), "0x%s", 4803 crypt_fpr_or_lkeyid (p)); 4804 mutt_str_replace (is_smime? &SmimeDefaultKey : &PgpSignAs, input_signas); 4805 crypt_free_key (&p); 4806 4807 msg->security |= SIGN; 4808 } 4809 *redraw = REDRAW_FULL; 4810 break; 4811 4812 case 'b': /* (b)oth */ 4813 msg->security |= (ENCRYPT | SIGN); 4814 break; 4815 4816 case 'p': /* (p)gp or s/(m)ime */ 4817 case 'm': 4818 is_smime = !is_smime; 4819 if (is_smime) 4820 { 4821 msg->security &= ~APPLICATION_PGP; 4822 msg->security |= APPLICATION_SMIME; 4823 } 4824 else 4825 { 4826 msg->security &= ~APPLICATION_SMIME; 4827 msg->security |= APPLICATION_PGP; 4828 } 4829 crypt_opportunistic_encrypt (msg); 4830 break; 4831 4832 case 'f': /* (f)orget it: kept for backward compatibility. */ 4833 case 'c': /* (c)lear */ 4834 msg->security &= ~(ENCRYPT | SIGN); 4835 break; 4836 4837 case 'F': /* (f)orget it or (c)lear in oppenc mode */ 4838 case 'C': 4839 msg->security &= ~SIGN; 4840 break; 4841 4842 case 'O': /* oppenc mode on */ 4843 msg->security |= OPPENCRYPT; 4844 crypt_opportunistic_encrypt (msg); 4845 break; 4846 4847 case 'o': /* oppenc mode off */ 4848 msg->security &= ~OPPENCRYPT; 4849 break; 4850 } 4851 } 4852 4853 return (msg->security); 4854} 4855 4856int pgp_gpgme_send_menu (HEADER *msg, int *redraw) 4857{ 4858 return gpgme_send_menu (msg, redraw, 0); 4859} 4860 4861int smime_gpgme_send_menu (HEADER *msg, int *redraw) 4862{ 4863 return gpgme_send_menu (msg, redraw, 1); 4864} 4865 4866static int verify_sender (HEADER *h, gpgme_protocol_t protocol) 4867{ 4868 ADDRESS *sender = NULL; 4869 unsigned int ret = 1; 4870 4871 if (h->env->from) 4872 { 4873 h->env->from = mutt_expand_aliases (h->env->from); 4874 sender = h->env->from; 4875 } 4876 else if (h->env->sender) 4877 { 4878 h->env->sender = mutt_expand_aliases (h->env->sender); 4879 sender = h->env->sender; 4880 } 4881 4882 if (sender) 4883 { 4884 if (signature_key) 4885 { 4886 gpgme_key_t key = signature_key; 4887 gpgme_user_id_t uid = NULL; 4888 int sender_length = 0; 4889 int uid_length = 0; 4890 4891 sender_length = strlen (sender->mailbox); 4892 for (uid = key->uids; uid && ret; uid = uid->next) 4893 { 4894 uid_length = strlen (uid->email); 4895 if (1 4896 && (uid->email[0] == '<') 4897 && (uid->email[uid_length - 1] == '>') 4898 && (uid_length == sender_length + 2)) 4899 { 4900 const char* at_sign = strchr(uid->email + 1, '@'); 4901 if (at_sign == NULL) 4902 { 4903 if (! strncmp (uid->email + 1, sender->mailbox, sender_length)) 4904 ret = 0; 4905 } 4906 else 4907 { 4908 /* 4909 * Assume address is 'mailbox@domainname'. 4910 * The mailbox part is case-sensitive, 4911 * the domainname is not. (RFC 2821) 4912 */ 4913 const char* tmp_email = uid->email + 1; 4914 const char* tmp_sender = sender->mailbox; 4915 /* length of mailbox part including '@' */ 4916 int mailbox_length = at_sign - tmp_email + 1; 4917 int domainname_length = sender_length - mailbox_length; 4918 int mailbox_match, domainname_match; 4919 4920 mailbox_match = (! strncmp (tmp_email, tmp_sender, 4921 mailbox_length)); 4922 tmp_email += mailbox_length; 4923 tmp_sender += mailbox_length; 4924 domainname_match = (! strncasecmp (tmp_email, tmp_sender, 4925 domainname_length)); 4926 if (mailbox_match && domainname_match) 4927 ret = 0; 4928 } 4929 } 4930 } 4931 } 4932 else 4933 mutt_any_key_to_continue (_("Failed to verify sender")); 4934 } 4935 else 4936 mutt_any_key_to_continue (_("Failed to figure out sender")); 4937 4938 if (signature_key) 4939 { 4940 gpgme_key_unref (signature_key); 4941 signature_key = NULL; 4942 } 4943 4944 return ret; 4945} 4946 4947int smime_gpgme_verify_sender (HEADER *h) 4948{ 4949 return verify_sender (h, GPGME_PROTOCOL_CMS); 4950} 4951 4952void mutt_gpgme_set_sender (const char *sender) 4953{ 4954 mutt_error ("[setting sender] mailbox: %s\n", sender); 4955 FREE (&current_sender); 4956 current_sender = safe_strdup (sender); 4957} 4958 4959 4960#endif