NeoMutt  2019-12-07-168-gc45f47
Teaching an old dog new tricks
DOXYGEN
crypt_gpgme.h File Reference

Wrapper for PGP/SMIME calls to GPGME. More...

#include <stdbool.h>
#include <stdio.h>
+ Include dependency graph for crypt_gpgme.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void pgp_gpgme_set_sender (const char *sender)
 Implements CryptModuleSpecs::set_sender() More...
 
int pgp_gpgme_application_handler (struct Body *m, struct State *s)
 Implements CryptModuleSpecs::application_handler() More...
 
int pgp_gpgme_check_traditional (FILE *fp, struct Body *b, bool just_one)
 Implements CryptModuleSpecs::pgp_check_traditional() More...
 
int pgp_gpgme_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
 Implements CryptModuleSpecs::decrypt_mime() More...
 
int pgp_gpgme_encrypted_handler (struct Body *a, struct State *s)
 Implements CryptModuleSpecs::encrypted_handler() More...
 
struct Bodypgp_gpgme_encrypt_message (struct Body *a, char *keylist, bool sign, const struct AddressList *from)
 Implements CryptModuleSpecs::pgp_encrypt_message() More...
 
char * pgp_gpgme_find_keys (struct AddressList *addrlist, bool oppenc_mode)
 Implements CryptModuleSpecs::find_keys() More...
 
void pgp_gpgme_init (void)
 Implements CryptModuleSpecs::init() More...
 
void pgp_gpgme_invoke_import (const char *fname)
 Implements CryptModuleSpecs::pgp_invoke_import() More...
 
struct Bodypgp_gpgme_make_key_attachment (void)
 Implements CryptModuleSpecs::pgp_make_key_attachment() More...
 
int pgp_gpgme_send_menu (struct Email *e)
 Implements CryptModuleSpecs::send_menu() More...
 
struct Bodypgp_gpgme_sign_message (struct Body *a, const struct AddressList *from)
 Implements CryptModuleSpecs::sign_message() More...
 
int pgp_gpgme_verify_one (struct Body *sigbdy, struct State *s, const char *tempfile)
 Implements CryptModuleSpecs::verify_one() More...
 
int smime_gpgme_application_handler (struct Body *a, struct State *s)
 Implements CryptModuleSpecs::application_handler() More...
 
struct Bodysmime_gpgme_build_smime_entity (struct Body *a, char *keylist)
 Implements CryptModuleSpecs::smime_build_smime_entity() More...
 
int smime_gpgme_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
 Implements CryptModuleSpecs::decrypt_mime() More...
 
char * smime_gpgme_find_keys (struct AddressList *addrlist, bool oppenc_mode)
 Implements CryptModuleSpecs::find_keys() More...
 
void smime_gpgme_init (void)
 Implements CryptModuleSpecs::init() More...
 
int smime_gpgme_send_menu (struct Email *e)
 Implements CryptModuleSpecs::send_menu() More...
 
struct Bodysmime_gpgme_sign_message (struct Body *a, const struct AddressList *from)
 Implements CryptModuleSpecs::sign_message() More...
 
int smime_gpgme_verify_one (struct Body *sigbdy, struct State *s, const char *tempfile)
 Implements CryptModuleSpecs::verify_one() More...
 
int smime_gpgme_verify_sender (struct Mailbox *m, struct Email *e)
 Implements CryptModuleSpecs::smime_verify_sender() More...
 
const char * mutt_gpgme_print_version (void)
 Get version of GPGME. More...
 
int mutt_gpgme_select_secret_key (struct Buffer *keyid)
 Select a private Autocrypt key for a new account. More...
 

Detailed Description

Wrapper for PGP/SMIME calls to GPGME.

Authors
  • g10 Code GmbH
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file crypt_gpgme.h.

Function Documentation

◆ pgp_gpgme_set_sender()

void pgp_gpgme_set_sender ( const char *  sender)

Implements CryptModuleSpecs::set_sender()

Definition at line 5856 of file crypt_gpgme.c.

5857 {
5858  mutt_debug(LL_DEBUG2, "setting to: %s\n", sender);
5859  FREE(&current_sender);
5860  current_sender = mutt_str_strdup(sender);
5861 }
Log at debug level 2.
Definition: logging.h:41
static char * current_sender
Definition: crypt_gpgme.c:140
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:

◆ pgp_gpgme_application_handler()

int pgp_gpgme_application_handler ( struct Body m,
struct State s 
)

Implements CryptModuleSpecs::application_handler()

Definition at line 2999 of file crypt_gpgme.c.

3000 {
3001  int needpass = -1;
3002  bool pgp_keyblock = false;
3003  bool clearsign = false;
3004  long bytes;
3005  LOFF_T last_pos;
3006  char buf[8192];
3007  FILE *fp_out = NULL;
3008 
3009  gpgme_error_t err = 0;
3010  gpgme_data_t armored_data = NULL;
3011 
3012  bool maybe_goodsig = true;
3013  bool have_any_sigs = false;
3014 
3015  char body_charset[256]; /* Only used for clearsigned messages. */
3016 
3017  mutt_debug(LL_DEBUG2, "Entering handler\n");
3018 
3019  /* For clearsigned messages we won't be able to get a character set
3020  * but we know that this may only be text thus we assume Latin-1 here. */
3021  if (!mutt_body_get_charset(m, body_charset, sizeof(body_charset)))
3022  mutt_str_strfcpy(body_charset, "iso-8859-1", sizeof(body_charset));
3023 
3024  fseeko(s->fp_in, m->offset, SEEK_SET);
3025  last_pos = m->offset;
3026 
3027  for (bytes = m->length; bytes > 0;)
3028  {
3029  if (!fgets(buf, sizeof(buf), s->fp_in))
3030  break;
3031 
3032  LOFF_T offset = ftello(s->fp_in);
3033  bytes -= (offset - last_pos); /* don't rely on mutt_str_strlen(buf) */
3034  last_pos = offset;
3035 
3036  size_t plen = mutt_str_startswith(buf, "-----BEGIN PGP ", CASE_MATCH);
3037  if (plen != 0)
3038  {
3039  clearsign = false;
3040 
3041  if (MESSAGE(buf + plen))
3042  needpass = 1;
3043  else if (SIGNED_MESSAGE(buf + plen))
3044  {
3045  clearsign = true;
3046  needpass = 0;
3047  }
3048  else if (PUBLIC_KEY_BLOCK(buf + plen))
3049  {
3050  needpass = 0;
3051  pgp_keyblock = true;
3052  }
3053  else
3054  {
3055  /* XXX we may wish to recode here */
3056  if (s->prefix)
3057  state_puts(s, s->prefix);
3058  state_puts(s, buf);
3059  continue;
3060  }
3061 
3062  have_any_sigs = (have_any_sigs || (clearsign && (s->flags & MUTT_VERIFY)));
3063 
3064  /* Copy PGP material to an data container */
3065  armored_data = file_to_data_object(s->fp_in, m->offset, m->length);
3066  /* Invoke PGP if needed */
3067  if (pgp_keyblock)
3068  {
3069  pgp_gpgme_extract_keys(armored_data, &fp_out);
3070  }
3071  else if (!clearsign || (s->flags & MUTT_VERIFY))
3072  {
3073  gpgme_data_t plaintext = create_gpgme_data();
3074  gpgme_ctx_t ctx = create_gpgme_context(false);
3075 
3076  if (clearsign)
3077  err = gpgme_op_verify(ctx, armored_data, NULL, plaintext);
3078  else
3079  {
3080  err = gpgme_op_decrypt_verify(ctx, armored_data, plaintext);
3081  if (gpg_err_code(err) == GPG_ERR_NO_DATA)
3082  {
3083  /* Decrypt verify can't handle signed only messages. */
3084  gpgme_data_seek(armored_data, 0, SEEK_SET);
3085  /* Must release plaintext so that we supply an uninitialized object. */
3086  gpgme_data_release(plaintext);
3087  plaintext = create_gpgme_data();
3088  err = gpgme_op_verify(ctx, armored_data, NULL, plaintext);
3089  }
3090  }
3091  redraw_if_needed(ctx);
3092 
3093  if (err != 0)
3094  {
3095  char errbuf[200];
3096 
3097  snprintf(errbuf, sizeof(errbuf) - 1,
3098  _("Error: decryption/verification failed: %s\n"), gpgme_strerror(err));
3099  state_puts(s, errbuf);
3100  }
3101  else
3102  {
3103  /* Decryption/Verification succeeded */
3104 
3105  mutt_message(_("PGP message successfully decrypted"));
3106 
3107  bool sig_stat = false;
3108  char *tmpfname = NULL;
3109 
3110  {
3111  /* Check whether signatures have been verified. */
3112  gpgme_verify_result_t verify_result = gpgme_op_verify_result(ctx);
3113  if (verify_result->signatures)
3114  sig_stat = true;
3115  }
3116 
3117  have_any_sigs = false;
3118  maybe_goodsig = false;
3119  if ((s->flags & MUTT_DISPLAY) && sig_stat)
3120  {
3121  int res, idx;
3122  bool anybad = false;
3123 
3124  state_attach_puts(s, _("[-- Begin signature information --]\n"));
3125  have_any_sigs = true;
3126  for (idx = 0; (res = show_one_sig_status(ctx, idx, s)) != -1; idx++)
3127  {
3128  if (res == 1)
3129  anybad = true;
3130  }
3131  if (!anybad && idx)
3132  maybe_goodsig = true;
3133 
3134  state_attach_puts(s, _("[-- End signature information --]\n\n"));
3135  }
3136 
3137  tmpfname = data_object_to_tempfile(plaintext, &fp_out);
3138  if (tmpfname)
3139  {
3140  unlink(tmpfname);
3141  FREE(&tmpfname);
3142  }
3143  else
3144  {
3145  mutt_file_fclose(&fp_out);
3146  state_puts(s, _("Error: copy data failed\n"));
3147  }
3148  }
3149  gpgme_data_release(plaintext);
3150  gpgme_release(ctx);
3151  }
3152 
3153  /* Now, copy cleartext to the screen. NOTE - we expect that PGP
3154  * outputs utf-8 cleartext. This may not always be true, but it
3155  * seems to be a reasonable guess. */
3156  if (s->flags & MUTT_DISPLAY)
3157  {
3158  if (needpass)
3159  state_attach_puts(s, _("[-- BEGIN PGP MESSAGE --]\n\n"));
3160  else if (pgp_keyblock)
3161  state_attach_puts(s, _("[-- BEGIN PGP PUBLIC KEY BLOCK --]\n"));
3162  else
3163  state_attach_puts(s, _("[-- BEGIN PGP SIGNED MESSAGE --]\n\n"));
3164  }
3165 
3166  if (clearsign)
3167  {
3168  copy_clearsigned(armored_data, s, body_charset);
3169  }
3170  else if (fp_out)
3171  {
3172  int c;
3173  rewind(fp_out);
3174  struct FgetConv *fc = mutt_ch_fgetconv_open(fp_out, "utf-8", C_Charset, 0);
3175  while ((c = mutt_ch_fgetconv(fc)) != EOF)
3176  {
3177  state_putc(s, c);
3178  if ((c == '\n') && s->prefix)
3179  state_puts(s, s->prefix);
3180  }
3182  }
3183 
3184  if (s->flags & MUTT_DISPLAY)
3185  {
3186  state_putc(s, '\n');
3187  if (needpass)
3188  state_attach_puts(s, _("[-- END PGP MESSAGE --]\n"));
3189  else if (pgp_keyblock)
3190  state_attach_puts(s, _("[-- END PGP PUBLIC KEY BLOCK --]\n"));
3191  else
3192  state_attach_puts(s, _("[-- END PGP SIGNED MESSAGE --]\n"));
3193  }
3194 
3195  gpgme_data_release(armored_data);
3196  mutt_file_fclose(&fp_out);
3197  }
3198  else
3199  {
3200  /* A traditional PGP part may mix signed and unsigned content */
3201  /* XXX we may wish to recode here */
3202  if (s->prefix)
3203  state_puts(s, s->prefix);
3204  state_puts(s, buf);
3205  }
3206  }
3207 
3208  m->goodsig = (maybe_goodsig && have_any_sigs);
3209 
3210  if (needpass == -1)
3211  {
3213  s, _("[-- Error: could not find beginning of PGP message --]\n\n"));
3214  return 1;
3215  }
3216  mutt_debug(LL_DEBUG2, "Leaving handler\n");
3217 
3218  return err;
3219 }
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
static gpgme_data_t file_to_data_object(FILE *fp, long offset, size_t length)
Create GPGME data object from file.
Definition: crypt_gpgme.c:926
#define state_puts(STATE, STR)
Definition: state.h:55
static char * data_object_to_tempfile(gpgme_data_t data, FILE **fp_ret)
Copy a data object to a temporary file.
Definition: crypt_gpgme.c:994
int mutt_ch_fgetconv(struct FgetConv *fc)
Convert a file&#39;s character set.
Definition: charset.c:902
#define SIGNED_MESSAGE(_y)
Definition: crypt_gpgme.c:146
#define mutt_message(...)
Definition: logging.h:83
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
#define PUBLIC_KEY_BLOCK(_y)
Definition: crypt_gpgme.c:147
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
Match case when comparing strings.
Definition: string2.h:67
FILE * fp_in
File to read from.
Definition: state.h:46
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
#define MESSAGE(_y)
Definition: crypt_gpgme.c:145
Log at debug level 2.
Definition: logging.h:41
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
static gpgme_ctx_t create_gpgme_context(bool for_smime)
Create a new GPGME context.
Definition: crypt_gpgme.c:760
bool goodsig
Good cryptographic signature.
Definition: body.h:75
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
#define MUTT_VERIFY
Perform signature verification.
Definition: state.h:33
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
static int pgp_gpgme_extract_keys(gpgme_data_t keydata, FILE **fp)
Write PGP keys to a file.
Definition: crypt_gpgme.c:2591
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body&#39;s character set.
Definition: sendlib.c:1460
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
void state_attach_puts(struct State *s, const char *t)
Write a string to the state.
Definition: state.c:70
void mutt_ch_fgetconv_close(struct FgetConv **fc)
Close an fgetconv handle.
Definition: charset.c:882
static gpgme_data_t create_gpgme_data(void)
Create a new GPGME data object.
Definition: crypt_gpgme.c:798
#define FREE(x)
Definition: memory.h:40
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:54
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define state_putc(STATE, STR)
Definition: state.h:56
struct FgetConv * mutt_ch_fgetconv_open(FILE *fp, const char *from, const char *to, int flags)
Prepare a file for charset conversion.
Definition: charset.c:852
static void redraw_if_needed(gpgme_ctx_t ctx)
accommodate for a redraw if needed
Definition: crypt_gpgme.c:204
Cursor for converting a file&#39;s encoding.
Definition: charset.h:41
static int show_one_sig_status(gpgme_ctx_t ctx, int idx, struct State *s)
Show information about one signature.
Definition: crypt_gpgme.c:1956
static void copy_clearsigned(gpgme_data_t data, struct State *s, char *charset)
Copy a clearsigned message.
Definition: crypt_gpgme.c:2943
+ Here is the call graph for this function:

◆ pgp_gpgme_check_traditional()

int pgp_gpgme_check_traditional ( FILE *  fp,
struct Body b,
bool  just_one 
)

Implements CryptModuleSpecs::pgp_check_traditional()

Definition at line 2809 of file crypt_gpgme.c.

2810 {
2811  int rc = 0;
2812  for (; b; b = b->next)
2813  {
2814  if (!just_one && is_multipart(b))
2815  rc = (pgp_gpgme_check_traditional(fp, b->parts, false) || rc);
2816  else if (b->type == TYPE_TEXT)
2817  {
2819  if (r)
2820  rc = (rc || r);
2821  else
2822  rc = (pgp_check_traditional_one_body(fp, b) || rc);
2823  }
2824 
2825  if (just_one)
2826  break;
2827  }
2828  return rc;
2829 }
int pgp_gpgme_check_traditional(FILE *fp, struct Body *b, bool just_one)
Implements CryptModuleSpecs::pgp_check_traditional()
Definition: crypt_gpgme.c:2809
#define is_multipart(body)
Definition: mime.h:77
struct Body * next
next attachment in the list
Definition: body.h:53
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:121
static int pgp_check_traditional_one_body(FILE *fp, struct Body *b)
Check one inline PGP body part.
Definition: crypt_gpgme.c:2745
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:563
FILE * fp
Definition: charset.h:43
Type: &#39;text/*&#39;.
Definition: mime.h:38
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_gpgme_decrypt_mime()

int pgp_gpgme_decrypt_mime ( FILE *  fp_in,
FILE **  fp_out,
struct Body b,
struct Body **  cur 
)

Implements CryptModuleSpecs::decrypt_mime()

Definition at line 2379 of file crypt_gpgme.c.

2380 {
2381  struct State s = { 0 };
2382  struct Body *first_part = b;
2383  int is_signed = 0;
2384  bool need_decode = false;
2385  int saved_type = 0;
2386  LOFF_T saved_offset = 0;
2387  size_t saved_length = 0;
2388  FILE *fp_decoded = NULL;
2389  int rc = 0;
2390 
2391  first_part->goodsig = false;
2392  first_part->warnsig = false;
2393 
2395  {
2396  b = b->parts->next;
2397  /* Some clients improperly encode the octetstream part. */
2398  if (b->encoding != ENC_7BIT)
2399  need_decode = true;
2400  }
2402  {
2403  b = b->parts->next->next;
2404  need_decode = true;
2405  }
2406  else
2407  return -1;
2408 
2409  s.fp_in = fp_in;
2410 
2411  if (need_decode)
2412  {
2413  saved_type = b->type;
2414  saved_offset = b->offset;
2415  saved_length = b->length;
2416 
2417  fp_decoded = mutt_file_mkstemp();
2418  if (!fp_decoded)
2419  {
2420  mutt_perror(_("Can't create temporary file"));
2421  return -1;
2422  }
2423 
2424  fseeko(s.fp_in, b->offset, SEEK_SET);
2425  s.fp_out = fp_decoded;
2426 
2427  mutt_decode_attachment(b, &s);
2428 
2429  fflush(fp_decoded);
2430  b->length = ftello(fp_decoded);
2431  b->offset = 0;
2432  rewind(fp_decoded);
2433  s.fp_in = fp_decoded;
2434  s.fp_out = 0;
2435  }
2436 
2437  *fp_out = mutt_file_mkstemp();
2438  if (!*fp_out)
2439  {
2440  mutt_perror(_("Can't create temporary file"));
2441  rc = -1;
2442  goto bail;
2443  }
2444 
2445  *cur = decrypt_part(b, &s, *fp_out, false, &is_signed);
2446  if (*cur)
2447  {
2448  rewind(*fp_out);
2449  if (is_signed > 0)
2450  first_part->goodsig = true;
2451  }
2452  else
2453  {
2454  rc = -1;
2455  mutt_file_fclose(fp_out);
2456  }
2457 
2458 bail:
2459  if (need_decode)
2460  {
2461  b->type = saved_type;
2462  b->length = saved_length;
2463  b->offset = saved_offset;
2464  mutt_file_fclose(&fp_decoded);
2465  }
2466 
2467  return rc;
2468 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1793
#define mutt_perror(...)
Definition: logging.h:85
7-bit text
Definition: mime.h:49
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:481
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
The body of an email.
Definition: body.h:34
static struct Body * decrypt_part(struct Body *a, struct State *s, FILE *fp_out, bool is_smime, int *r_is_signed)
Decrypt a PGP or SMIME message.
Definition: crypt_gpgme.c:2227
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
bool goodsig
Good cryptographic signature.
Definition: body.h:75
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define mutt_file_mkstemp()
Definition: file.h:105
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:518
unsigned int type
content-type primary type
Definition: body.h:65
Keep track when processing files.
Definition: state.h:44
bool warnsig
Maybe good signature.
Definition: body.h:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_gpgme_encrypted_handler()

int pgp_gpgme_encrypted_handler ( struct Body a,
struct State s 
)

Implements CryptModuleSpecs::encrypted_handler()

This handler is passed the application/octet-stream directly. The caller must propagate a->goodsig to its parent.

Definition at line 3227 of file crypt_gpgme.c.

3228 {
3229  int is_signed;
3230  int rc = 0;
3231 
3232  mutt_debug(LL_DEBUG2, "Entering handler\n");
3233 
3234  FILE *fp_out = mutt_file_mkstemp();
3235  if (!fp_out)
3236  {
3237  mutt_perror(_("Can't create temporary file"));
3238  if (s->flags & MUTT_DISPLAY)
3239  {
3241  _("[-- Error: could not create temporary file --]\n"));
3242  }
3243  return -1;
3244  }
3245 
3246  struct Body *tattach = decrypt_part(a, s, fp_out, false, &is_signed);
3247  if (tattach)
3248  {
3249  tattach->goodsig = is_signed > 0;
3250 
3251  if (s->flags & MUTT_DISPLAY)
3252  {
3254  s, is_signed ?
3255  _("[-- The following data is PGP/MIME signed and encrypted "
3256  "--]\n\n") :
3257  _("[-- The following data is PGP/MIME encrypted --]\n\n"));
3258  mutt_protected_headers_handler(tattach, s);
3259  }
3260 
3261  /* Store any protected headers in the parent so they can be
3262  * accessed for index updates after the handler recursion is done.
3263  * This is done before the handler to prevent a nested encrypted
3264  * handler from freeing the headers. */
3266  a->mime_headers = tattach->mime_headers;
3267  tattach->mime_headers = NULL;
3268 
3269  {
3270  FILE *fp_save = s->fp_in;
3271  s->fp_in = fp_out;
3272  rc = mutt_body_handler(tattach, s);
3273  s->fp_in = fp_save;
3274  }
3275 
3276  /* Embedded multipart signed protected headers override the
3277  * encrypted headers. We need to do this after the handler so
3278  * they can be printed in the pager. */
3279  if (mutt_is_multipart_signed(tattach) && tattach->parts && tattach->parts->mime_headers)
3280  {
3282  a->mime_headers = tattach->parts->mime_headers;
3283  tattach->parts->mime_headers = NULL;
3284  }
3285 
3286  /* if a multipart/signed is the _only_ sub-part of a
3287  * multipart/encrypted, cache signature verification
3288  * status. */
3289  if (mutt_is_multipart_signed(tattach) && !tattach->next)
3290  a->goodsig |= tattach->goodsig;
3291 
3292  if (s->flags & MUTT_DISPLAY)
3293  {
3294  state_puts(s, "\n");
3296  s, is_signed ?
3297  _("[-- End of PGP/MIME signed and encrypted data --]\n") :
3298  _("[-- End of PGP/MIME encrypted data --]\n"));
3299  }
3300 
3301  mutt_body_free(&tattach);
3302  mutt_message(_("PGP message successfully decrypted"));
3303  }
3304  else
3305  {
3306  if (!OptAutocryptGpgme)
3307  {
3308  mutt_error(_("Could not decrypt PGP message"));
3309  }
3310  rc = -1;
3311  }
3312 
3313  mutt_file_fclose(&fp_out);
3314  mutt_debug(LL_DEBUG2, "Leaving handler\n");
3315 
3316  return rc;
3317 }
int mutt_protected_headers_handler(struct Body *a, struct State *s)
Process a protected header - Implements handler_t.
Definition: crypt.c:1100
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
#define state_puts(STATE, STR)
Definition: state.h:55
#define mutt_perror(...)
Definition: logging.h:85
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
WHERE bool OptAutocryptGpgme
(pseudo) use Autocrypt context inside ncrypt/crypt_gpgme.c
Definition: options.h:32
FILE * fp_in
File to read from.
Definition: state.h:46
The body of an email.
Definition: body.h:34
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
Log at debug level 2.
Definition: logging.h:41
static struct Body * decrypt_part(struct Body *a, struct State *s, FILE *fp_out, bool is_smime, int *r_is_signed)
Decrypt a PGP or SMIME message.
Definition: crypt_gpgme.c:2227
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:416
bool goodsig
Good cryptographic signature.
Definition: body.h:75
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define mutt_file_mkstemp()
Definition: file.h:105
void state_attach_puts(struct State *s, const char *t)
Write a string to the state.
Definition: state.c:70
#define mutt_error(...)
Definition: logging.h:84
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1549
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_gpgme_encrypt_message()

struct Body* pgp_gpgme_encrypt_message ( struct Body a,
char *  keylist,
bool  sign,
const struct AddressList *  from 
)

Implements CryptModuleSpecs::pgp_encrypt_message()

Definition at line 1572 of file crypt_gpgme.c.

1574 {
1575  if (sign)
1577  gpgme_data_t plaintext = body_to_data_object(a, false);
1578  if (!plaintext)
1579  return NULL;
1580 
1581  char *outfile = encrypt_gpgme_object(plaintext, keylist, false, sign, from);
1582  gpgme_data_release(plaintext);
1583  if (!outfile)
1584  return NULL;
1585 
1586  struct Body *t = mutt_body_new();
1587  t->type = TYPE_MULTIPART;
1588  t->subtype = mutt_str_strdup("encrypted");
1589  t->encoding = ENC_7BIT;
1590  t->use_disp = false;
1591  t->disposition = DISP_INLINE;
1592 
1594  mutt_param_set(&t->parameter, "protocol", "application/pgp-encrypted");
1595 
1596  t->parts = mutt_body_new();
1597  t->parts->type = TYPE_APPLICATION;
1598  t->parts->subtype = mutt_str_strdup("pgp-encrypted");
1599  t->parts->encoding = ENC_7BIT;
1600 
1601  t->parts->next = mutt_body_new();
1603  t->parts->next->subtype = mutt_str_strdup("octet-stream");
1604  t->parts->next->encoding = ENC_7BIT;
1605  t->parts->next->filename = outfile;
1606  t->parts->next->use_disp = true;
1608  t->parts->next->unlink = true; /* delete after sending the message */
1609  t->parts->next->d_filename = mutt_str_strdup("msg.asc"); /* non pgp/mime
1610  can save */
1611 
1612  return t;
1613 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
7-bit text
Definition: mime.h:49
void crypt_convert_to_7bit(struct Body *a)
Convert an email to 7bit encoding.
Definition: crypt.c:814
static char * encrypt_gpgme_object(gpgme_data_t plaintext, char *keylist, bool use_smime, bool combined_signed, const struct AddressList *from)
Encrypt the GPGPME data object.
Definition: crypt_gpgme.c:1293
struct Body * next
next attachment in the list
Definition: body.h:53
The body of an email.
Definition: body.h:34
unsigned int disposition
content-disposition
Definition: body.h:67
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
void mutt_generate_boundary(struct ParameterList *pl)
Create a unique boundary id for a MIME part.
Definition: sendlib.c:637
Content is attached.
Definition: mime.h:63
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
char * subtype
content-type subtype
Definition: body.h:37
static gpgme_data_t body_to_data_object(struct Body *a, bool convert)
Create GPGME object from the mail body.
Definition: crypt_gpgme.c:854
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
Content is inline.
Definition: mime.h:62
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Type: &#39;application/*&#39;.
Definition: mime.h:33
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_gpgme_find_keys()

char* pgp_gpgme_find_keys ( struct AddressList *  addrlist,
bool  oppenc_mode 
)

Implements CryptModuleSpecs::find_keys()

Definition at line 5358 of file crypt_gpgme.c.

5359 {
5360  return find_keys(addrlist, APPLICATION_PGP, oppenc_mode);
5361 }
static char * find_keys(struct AddressList *addrlist, unsigned int app, bool oppenc_mode)
Find keys of the recipients of the message.
Definition: crypt_gpgme.c:5236
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:135
+ Here is the call graph for this function:

◆ pgp_gpgme_init()

void pgp_gpgme_init ( void  )

Implements CryptModuleSpecs::init()

Definition at line 5572 of file crypt_gpgme.c.

5573 {
5574  init_common();
5575  init_pgp();
5576 }
static void init_common(void)
Initialise code common to PGP and SMIME parts of GPGME.
Definition: crypt_gpgme.c:5531
static void init_pgp(void)
Initialise the PGP crypto backend.
Definition: crypt_gpgme.c:5550
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_gpgme_invoke_import()

void pgp_gpgme_invoke_import ( const char *  fname)

Implements CryptModuleSpecs::pgp_invoke_import()

Definition at line 2834 of file crypt_gpgme.c.

2835 {
2836  gpgme_ctx_t ctx = create_gpgme_context(false);
2837  gpgme_data_t keydata = NULL;
2838  gpgme_import_result_t impres;
2839  gpgme_import_status_t st;
2840  bool any;
2841 
2842  FILE *fp_in = mutt_file_fopen(fname, "r");
2843  if (!fp_in)
2844  {
2845  mutt_perror(fname);
2846  goto leave;
2847  }
2848  /* Note that the stream, "fp_in", needs to be kept open while the keydata
2849  * is used. */
2850  gpgme_error_t err = gpgme_data_new_from_stream(&keydata, fp_in);
2851  if (err != GPG_ERR_NO_ERROR)
2852  {
2853  mutt_error(_("error allocating data object: %s"), gpgme_strerror(err));
2854  goto leave;
2855  }
2856 
2857  err = gpgme_op_import(ctx, keydata);
2858  if (err != 0)
2859  {
2860  mutt_error(_("Error importing key: %s"), gpgme_strerror(err));
2861  goto leave;
2862  }
2863 
2864  /* Print infos about the imported keys to stdout. */
2865  impres = gpgme_op_import_result(ctx);
2866  if (!impres)
2867  {
2868  fputs("oops: no import result returned\n", stdout);
2869  goto leave;
2870  }
2871 
2872  for (st = impres->imports; st; st = st->next)
2873  {
2874  if (st->result)
2875  continue;
2876  printf("key %s imported (", NONULL(st->fpr));
2877  /* Note that we use the singular even if it is possible that
2878  * several uids etc are new. This simply looks better. */
2879  any = false;
2880  if (st->status & GPGME_IMPORT_SECRET)
2881  {
2882  printf("secret parts");
2883  any = true;
2884  }
2885  if ((st->status & GPGME_IMPORT_NEW))
2886  {
2887  printf("%snew key", any ? ", " : "");
2888  any = true;
2889  }
2890  if ((st->status & GPGME_IMPORT_UID))
2891  {
2892  printf("%snew uid", any ? ", " : "");
2893  any = true;
2894  }
2895  if ((st->status & GPGME_IMPORT_SIG))
2896  {
2897  printf("%snew sig", any ? ", " : "");
2898  any = true;
2899  }
2900  if ((st->status & GPGME_IMPORT_SUBKEY))
2901  {
2902  printf("%snew subkey", any ? ", " : "");
2903  any = true;
2904  }
2905  printf("%s)\n", any ? "" : "not changed");
2906  /* Fixme: Should we lookup each imported key and print more infos? */
2907  }
2908  /* Now print keys which failed the import. Unfortunately in most
2909  * cases gpg will bail out early and not tell gpgme about. */
2910  /* FIXME: We could instead use the new GPGME_AUDITLOG_DIAG to show
2911  * the actual gpg diagnostics. But I fear that would clutter the
2912  * output too much. Maybe a dedicated prompt or option to do this
2913  * would be helpful. */
2914  for (st = impres->imports; st; st = st->next)
2915  {
2916  if (st->result == 0)
2917  continue;
2918  printf("key %s import failed: %s\n", NONULL(st->fpr), gpgme_strerror(st->result));
2919  }
2920  fflush(stdout);
2921 
2922 leave:
2923  gpgme_release(ctx);
2924  gpgme_data_release(keydata);
2925  mutt_file_fclose(&fp_in);
2926 }
#define NONULL(x)
Definition: string2.h:37
#define mutt_perror(...)
Definition: logging.h:85
#define _(a)
Definition: message.h:28
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
static gpgme_ctx_t create_gpgme_context(bool for_smime)
Create a new GPGME context.
Definition: crypt_gpgme.c:760
#define mutt_error(...)
Definition: logging.h:84
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:585
+ Here is the call graph for this function:

◆ pgp_gpgme_make_key_attachment()

struct Body* pgp_gpgme_make_key_attachment ( void  )

Implements CryptModuleSpecs::pgp_make_key_attachment()

Definition at line 5465 of file crypt_gpgme.c.

5466 {
5467 #ifdef HAVE_GPGME_OP_EXPORT_KEYS
5468  gpgme_ctx_t context = NULL;
5469  gpgme_key_t export_keys[2] = { 0 };
5470  gpgme_data_t keydata = NULL;
5471  gpgme_error_t err;
5472  struct Body *att = NULL;
5473  char buf[1024];
5474  struct stat sb;
5475 
5476  OptPgpCheckTrust = false;
5477 
5478  struct CryptKeyInfo *key = crypt_ask_for_key(_("Please enter the key ID: "), NULL,
5480  if (!key)
5481  goto bail;
5482  export_keys[0] = key->kobj;
5483  export_keys[1] = NULL;
5484 
5485  context = create_gpgme_context(false);
5486  gpgme_set_armor(context, 1);
5487  keydata = create_gpgme_data();
5488  err = gpgme_op_export_keys(context, export_keys, 0, keydata);
5489  if (err != GPG_ERR_NO_ERROR)
5490  {
5491  mutt_error(_("Error exporting key: %s"), gpgme_strerror(err));
5492  goto bail;
5493  }
5494 
5495  char *tempf = data_object_to_tempfile(keydata, NULL);
5496  if (!tempf)
5497  goto bail;
5498 
5499  att = mutt_body_new();
5500  /* tempf is a newly allocated string, so this is correct: */
5501  att->filename = tempf;
5502  att->unlink = true;
5503  att->use_disp = false;
5504  att->type = TYPE_APPLICATION;
5505  att->subtype = mutt_str_strdup("pgp-keys");
5506  /* L10N: MIME description for exported (attached) keys.
5507  You can translate this entry to a non-ASCII string (it will be encoded),
5508  but it may be safer to keep it untranslated. */
5509  snprintf(buf, sizeof(buf), _("PGP Key 0x%s"), crypt_keyid(key));
5510  att->description = mutt_str_strdup(buf);
5511  mutt_update_encoding(att);
5512 
5513  stat(tempf, &sb);
5514  att->length = sb.st_size;
5515 
5516 bail:
5517  crypt_key_free(&key);
5518  gpgme_data_release(keydata);
5519  gpgme_release(context);
5520 
5521  return att;
5522 #else
5523  mutt_error("gpgme_op_export_keys not supported");
5524  return NULL;
5525 #endif
5526 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
static char * data_object_to_tempfile(gpgme_data_t data, FILE **fp_ret)
Copy a data object to a temporary file.
Definition: crypt_gpgme.c:994
static void crypt_key_free(struct CryptKeyInfo **keylist)
Release all the keys in a list.
Definition: crypt_gpgme.c:639
#define _(a)
Definition: message.h:28
The body of an email.
Definition: body.h:34
A stored PGP key.
Definition: crypt_gpgme.c:119
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1484
static gpgme_ctx_t create_gpgme_context(bool for_smime)
Create a new GPGME context.
Definition: crypt_gpgme.c:760
char * subtype
content-type subtype
Definition: body.h:37
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:135
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
#define KEYFLAG_NO_FLAGS
No flags are set.
Definition: lib.h:171
gpgme_key_t kobj
Definition: crypt_gpgme.c:122
static struct CryptKeyInfo * crypt_ask_for_key(char *tag, char *whatfor, KeyFlags abilities, unsigned int app, int *forced_valid)
Ask the user for a key.
Definition: crypt_gpgme.c:5169
WHERE bool OptPgpCheckTrust
(pseudo) used by pgp_select_key()
Definition: options.h:48
char * description
content-description
Definition: body.h:40
unsigned int type
content-type primary type
Definition: body.h:65
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
static gpgme_data_t create_gpgme_data(void)
Create a new GPGME data object.
Definition: crypt_gpgme.c:798
#define mutt_error(...)
Definition: logging.h:84
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
Type: &#39;application/*&#39;.
Definition: mime.h:33
static const char * crypt_keyid(struct CryptKeyInfo *k)
Find the ID for the key.
Definition: crypt_gpgme.c:473
+ Here is the call graph for this function:

◆ pgp_gpgme_send_menu()

int pgp_gpgme_send_menu ( struct Email e)

Implements CryptModuleSpecs::send_menu()

Definition at line 5754 of file crypt_gpgme.c.

5755 {
5756  return gpgme_send_menu(e, 0);
5757 }
static int gpgme_send_menu(struct Email *e, int is_smime)
Show the user the encryption/signing menu.
Definition: crypt_gpgme.c:5593
+ Here is the call graph for this function:

◆ pgp_gpgme_sign_message()

struct Body* pgp_gpgme_sign_message ( struct Body a,
const struct AddressList *  from 
)

Implements CryptModuleSpecs::sign_message()

Definition at line 1556 of file crypt_gpgme.c.

1557 {
1558  return sign_message(a, from, false);
1559 }
static struct Body * sign_message(struct Body *a, const struct AddressList *from, bool use_smime)
Sign a message.
Definition: crypt_gpgme.c:1435
+ Here is the call graph for this function:

◆ pgp_gpgme_verify_one()

int pgp_gpgme_verify_one ( struct Body sigbdy,
struct State s,
const char *  tempfile 
)

Implements CryptModuleSpecs::verify_one()

Definition at line 2201 of file crypt_gpgme.c.

2202 {
2203  return verify_one(sigbdy, s, tempfile, false);
2204 }
static int verify_one(struct Body *sigbdy, struct State *s, const char *tempfile, bool is_smime)
Do the actual verification step.
Definition: crypt_gpgme.c:2076
+ Here is the call graph for this function:

◆ smime_gpgme_application_handler()

int smime_gpgme_application_handler ( struct Body a,
struct State s 
)

Implements CryptModuleSpecs::application_handler()

Definition at line 3322 of file crypt_gpgme.c.

3323 {
3324  int is_signed = 0;
3325  int rc = 0;
3326 
3327  mutt_debug(LL_DEBUG2, "Entering handler\n");
3328 
3329  /* clear out any mime headers before the handler, so they can't be spoofed. */
3331  a->warnsig = false;
3332  FILE *fp_out = mutt_file_mkstemp();
3333  if (!fp_out)
3334  {
3335  mutt_perror(_("Can't create temporary file"));
3336  if (s->flags & MUTT_DISPLAY)
3337  {
3339  _("[-- Error: could not create temporary file --]\n"));
3340  }
3341  return -1;
3342  }
3343 
3344  struct Body *tattach = decrypt_part(a, s, fp_out, true, &is_signed);
3345  if (tattach)
3346  {
3347  tattach->goodsig = is_signed > 0;
3348 
3349  if (s->flags & MUTT_DISPLAY)
3350  {
3352  s, is_signed ?
3353  _("[-- The following data is S/MIME signed --]\n\n") :
3354  _("[-- The following data is S/MIME encrypted --]\n\n"));
3355  mutt_protected_headers_handler(tattach, s);
3356  }
3357 
3358  /* Store any protected headers in the parent so they can be
3359  * accessed for index updates after the handler recursion is done.
3360  * This is done before the handler to prevent a nested encrypted
3361  * handler from freeing the headers. */
3363  a->mime_headers = tattach->mime_headers;
3364  tattach->mime_headers = NULL;
3365 
3366  {
3367  FILE *fp_save = s->fp_in;
3368  s->fp_in = fp_out;
3369  rc = mutt_body_handler(tattach, s);
3370  s->fp_in = fp_save;
3371  }
3372 
3373  /* Embedded multipart signed protected headers override the
3374  * encrypted headers. We need to do this after the handler so
3375  * they can be printed in the pager. */
3376  if (mutt_is_multipart_signed(tattach) && tattach->parts && tattach->parts->mime_headers)
3377  {
3379  a->mime_headers = tattach->parts->mime_headers;
3380  tattach->parts->mime_headers = NULL;
3381  }
3382 
3383  /* if a multipart/signed is the _only_ sub-part of a multipart/encrypted,
3384  * cache signature verification status. */
3385  if (mutt_is_multipart_signed(tattach) && !tattach->next)
3386  {
3387  a->goodsig = tattach->goodsig;
3388  if (!a->goodsig)
3389  a->warnsig = tattach->warnsig;
3390  }
3391  else if (tattach->goodsig)
3392  {
3393  a->goodsig = true;
3394  a->warnsig = tattach->warnsig;
3395  }
3396 
3397  if (s->flags & MUTT_DISPLAY)
3398  {
3399  state_puts(s, "\n");
3400  state_attach_puts(s, is_signed ?
3401  _("[-- End of S/MIME signed data --]\n") :
3402  _("[-- End of S/MIME encrypted data --]\n"));
3403  }
3404 
3405  mutt_body_free(&tattach);
3406  }
3407 
3408  mutt_file_fclose(&fp_out);
3409  mutt_debug(LL_DEBUG2, "Leaving handler\n");
3410 
3411  return rc;
3412 }
int mutt_protected_headers_handler(struct Body *a, struct State *s)
Process a protected header - Implements handler_t.
Definition: crypt.c:1100
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
#define state_puts(STATE, STR)
Definition: state.h:55
#define mutt_perror(...)
Definition: logging.h:85
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
FILE * fp_in
File to read from.
Definition: state.h:46
The body of an email.
Definition: body.h:34
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
Log at debug level 2.
Definition: logging.h:41
static struct Body * decrypt_part(struct Body *a, struct State *s, FILE *fp_out, bool is_smime, int *r_is_signed)
Decrypt a PGP or SMIME message.
Definition: crypt_gpgme.c:2227
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:416
bool goodsig
Good cryptographic signature.
Definition: body.h:75
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define mutt_file_mkstemp()
Definition: file.h:105
void state_attach_puts(struct State *s, const char *t)
Write a string to the state.
Definition: state.c:70
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1549
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
bool warnsig
Maybe good signature.
Definition: body.h:76
+ Here is the call graph for this function:

◆ smime_gpgme_build_smime_entity()

struct Body* smime_gpgme_build_smime_entity ( struct Body a,
char *  keylist 
)

Implements CryptModuleSpecs::smime_build_smime_entity()

Definition at line 1618 of file crypt_gpgme.c.

1619 {
1620  /* OpenSSL converts line endings to crlf when encrypting. Some clients
1621  * depend on this for signed+encrypted messages: they do not convert line
1622  * endings between decrypting and checking the signature. */
1623  gpgme_data_t plaintext = body_to_data_object(a, true);
1624  if (!plaintext)
1625  return NULL;
1626 
1627  char *outfile = encrypt_gpgme_object(plaintext, keylist, true, false, NULL);
1628  gpgme_data_release(plaintext);
1629  if (!outfile)
1630  return NULL;
1631 
1632  struct Body *t = mutt_body_new();
1633  t->type = TYPE_APPLICATION;
1634  t->subtype = mutt_str_strdup("pkcs7-mime");
1635  mutt_param_set(&t->parameter, "name", "smime.p7m");
1636  mutt_param_set(&t->parameter, "smime-type", "enveloped-data");
1637  t->encoding = ENC_BASE64; /* The output of OpenSSL SHOULD be binary */
1638  t->use_disp = true;
1639  t->disposition = DISP_ATTACH;
1640  t->d_filename = mutt_str_strdup("smime.p7m");
1641  t->filename = outfile;
1642  t->unlink = true; /* delete after sending the message */
1643  t->parts = 0;
1644  t->next = 0;
1645 
1646  return t;
1647 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
static char * encrypt_gpgme_object(gpgme_data_t plaintext, char *keylist, bool use_smime, bool combined_signed, const struct AddressList *from)
Encrypt the GPGPME data object.
Definition: crypt_gpgme.c:1293
struct Body * next
next attachment in the list
Definition: body.h:53
The body of an email.
Definition: body.h:34
unsigned int disposition
content-disposition
Definition: body.h:67
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
Content is attached.
Definition: mime.h:63
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:37
static gpgme_data_t body_to_data_object(struct Body *a, bool convert)
Create GPGME object from the mail body.
Definition: crypt_gpgme.c:854
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Type: &#39;application/*&#39;.
Definition: mime.h:33
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
+ Here is the call graph for this function:

◆ smime_gpgme_decrypt_mime()

int smime_gpgme_decrypt_mime ( FILE *  fp_in,
FILE **  fp_out,
struct Body b,
struct Body **  cur 
)

Implements CryptModuleSpecs::decrypt_mime()

Definition at line 2473 of file crypt_gpgme.c.

2474 {
2475  struct State s = { 0 };
2476  int is_signed;
2477  LOFF_T saved_b_offset;
2478  size_t saved_b_length;
2479  int saved_b_type;
2480 
2482  return -1;
2483 
2484  if (b->parts)
2485  return -1;
2486 
2487  /* Decode the body - we need to pass binary CMS to the
2488  * backend. The backend allows for Base64 encoded data but it does
2489  * not allow for QP which I have seen in some messages. So better
2490  * do it here. */
2491  saved_b_type = b->type;
2492  saved_b_offset = b->offset;
2493  saved_b_length = b->length;
2494  s.fp_in = fp_in;
2495  fseeko(s.fp_in, b->offset, SEEK_SET);
2496  FILE *fp_tmp = mutt_file_mkstemp();
2497  if (!fp_tmp)
2498  {
2499  mutt_perror(_("Can't create temporary file"));
2500  return -1;
2501  }
2502 
2503  s.fp_out = fp_tmp;
2504  mutt_decode_attachment(b, &s);
2505  fflush(fp_tmp);
2506  b->length = ftello(s.fp_out);
2507  b->offset = 0;
2508  rewind(fp_tmp);
2509 
2510  memset(&s, 0, sizeof(s));
2511  s.fp_in = fp_tmp;
2512  s.fp_out = 0;
2514  if (!*fp_out)
2515  {
2516  mutt_perror(_("Can't create temporary file"));
2517  return -1;
2518  }
2519 
2520  *cur = decrypt_part(b, &s, *fp_out, true, &is_signed);
2521  if (*cur)
2522  (*cur)->goodsig = is_signed > 0;
2523  b->type = saved_b_type;
2524  b->length = saved_b_length;
2525  b->offset = saved_b_offset;
2526  mutt_file_fclose(&fp_tmp);
2527  rewind(*fp_out);
2528  if (*cur && !is_signed && !(*cur)->parts && mutt_is_application_smime(*cur))
2529  {
2530  /* Assume that this is a opaque signed s/mime message. This is an ugly way
2531  * of doing it but we have anyway a problem with arbitrary encoded S/MIME
2532  * messages: Only the outer part may be encrypted. The entire mime parsing
2533  * should be revamped, probably by keeping the temporary files so that we
2534  * don't need to decrypt them all the time. Inner parts of an encrypted
2535  * part can then point into this file and there won't ever be a need to
2536  * decrypt again. This needs a partial rewrite of the MIME engine. */
2537  struct Body *bb = *cur;
2538 
2539  saved_b_type = bb->type;
2540  saved_b_offset = bb->offset;
2541  saved_b_length = bb->length;
2542  memset(&s, 0, sizeof(s));
2543  s.fp_in = *fp_out;
2544  fseeko(s.fp_in, bb->offset, SEEK_SET);
2545  FILE *fp_tmp2 = mutt_file_mkstemp();
2546  if (!fp_tmp2)
2547  {
2548  mutt_perror(_("Can't create temporary file"));
2549  return -1;
2550  }
2551 
2552  s.fp_out = fp_tmp2;
2553  mutt_decode_attachment(bb, &s);
2554  fflush(fp_tmp2);
2555  bb->length = ftello(s.fp_out);
2556  bb->offset = 0;
2557  rewind(fp_tmp2);
2558  mutt_file_fclose(fp_out);
2559 
2560  memset(&s, 0, sizeof(s));
2561  s.fp_in = fp_tmp2;
2562  s.fp_out = 0;
2563  *fp_out = mutt_file_mkstemp();
2564  if (!*fp_out)
2565  {
2566  mutt_perror(_("Can't create temporary file"));
2567  return -1;
2568  }
2569 
2570  struct Body *b_tmp = decrypt_part(bb, &s, *fp_out, true, &is_signed);
2571  if (b_tmp)
2572  b_tmp->goodsig = is_signed > 0;
2573  bb->type = saved_b_type;
2574  bb->length = saved_b_length;
2575  bb->offset = saved_b_offset;
2576  mutt_file_fclose(&fp_tmp2);
2577  rewind(*fp_out);
2578  mutt_body_free(cur);
2579  *cur = b_tmp;
2580  }
2581  return *cur ? 0 : -1;
2582 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1793
#define mutt_perror(...)
Definition: logging.h:85
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:122
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
The body of an email.
Definition: body.h:34
static struct Body * decrypt_part(struct Body *a, struct State *s, FILE *fp_out, bool is_smime, int *r_is_signed)
Decrypt a PGP or SMIME message.
Definition: crypt_gpgme.c:2227
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
bool goodsig
Good cryptographic signature.
Definition: body.h:75
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define mutt_file_mkstemp()
Definition: file.h:105
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:622
unsigned int type
content-type primary type
Definition: body.h:65
Keep track when processing files.
Definition: state.h:44
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
+ Here is the call graph for this function:

◆ smime_gpgme_find_keys()

char* smime_gpgme_find_keys ( struct AddressList *  addrlist,
bool  oppenc_mode 
)

Implements CryptModuleSpecs::find_keys()

Definition at line 5366 of file crypt_gpgme.c.

5367 {
5368  return find_keys(addrlist, APPLICATION_SMIME, oppenc_mode);
5369 }
static char * find_keys(struct AddressList *addrlist, unsigned int app, bool oppenc_mode)
Find keys of the recipients of the message.
Definition: crypt_gpgme.c:5236
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:136
+ Here is the call graph for this function:

◆ smime_gpgme_init()

void smime_gpgme_init ( void  )

Implements CryptModuleSpecs::init()

Definition at line 5581 of file crypt_gpgme.c.

5582 {
5583  init_common();
5584  init_smime();
5585 }
static void init_smime(void)
Initialise the SMIME crypto backend.
Definition: crypt_gpgme.c:5561
static void init_common(void)
Initialise code common to PGP and SMIME parts of GPGME.
Definition: crypt_gpgme.c:5531
+ Here is the call graph for this function:

◆ smime_gpgme_send_menu()

int smime_gpgme_send_menu ( struct Email e)

Implements CryptModuleSpecs::send_menu()

Definition at line 5762 of file crypt_gpgme.c.

5763 {
5764  return gpgme_send_menu(e, 1);
5765 }
static int gpgme_send_menu(struct Email *e, int is_smime)
Show the user the encryption/signing menu.
Definition: crypt_gpgme.c:5593
+ Here is the call graph for this function:

◆ smime_gpgme_sign_message()

struct Body* smime_gpgme_sign_message ( struct Body a,
const struct AddressList *  from 
)

Implements CryptModuleSpecs::sign_message()

Definition at line 1564 of file crypt_gpgme.c.

1565 {
1566  return sign_message(a, from, true);
1567 }
static struct Body * sign_message(struct Body *a, const struct AddressList *from, bool use_smime)
Sign a message.
Definition: crypt_gpgme.c:1435
+ Here is the call graph for this function:

◆ smime_gpgme_verify_one()

int smime_gpgme_verify_one ( struct Body sigbdy,
struct State s,
const char *  tempfile 
)

Implements CryptModuleSpecs::verify_one()

Definition at line 2209 of file crypt_gpgme.c.

2210 {
2211  return verify_one(sigbdy, s, tempfile, true);
2212 }
static int verify_one(struct Body *sigbdy, struct State *s, const char *tempfile, bool is_smime)
Do the actual verification step.
Definition: crypt_gpgme.c:2076
+ Here is the call graph for this function:

◆ smime_gpgme_verify_sender()

int smime_gpgme_verify_sender ( struct Mailbox m,
struct Email e 
)

Implements CryptModuleSpecs::smime_verify_sender()

Definition at line 5848 of file crypt_gpgme.c.

5849 {
5850  return verify_sender(e);
5851 }
static bool verify_sender(struct Email *e)
Verify the sender of a message.
Definition: crypt_gpgme.c:5772
+ Here is the call graph for this function:

◆ mutt_gpgme_print_version()

const char* mutt_gpgme_print_version ( void  )

Get version of GPGME.

Return values
ptrGPGME version string

Definition at line 5867 of file crypt_gpgme.c.

5868 {
5869  return GPGME_VERSION;
5870 }
+ Here is the caller graph for this function:

◆ mutt_gpgme_select_secret_key()

int mutt_gpgme_select_secret_key ( struct Buffer keyid)

Select a private Autocrypt key for a new account.

Parameters
keyidAutocrypt Key id
Return values
0Success
-1Error

Unfortunately, the internal ncrypt/crypt_gpgme.c functions use CryptKeyInfo, and so aren't exportable.

This function queries all private keys, provides the crypt_select_keys() menu, and returns the selected key fingerprint in keyid.

Definition at line 5383 of file crypt_gpgme.c.

5384 {
5385  int rc = -1, junk;
5386  gpgme_error_t err;
5387  gpgme_key_t key = NULL;
5388  gpgme_user_id_t uid = NULL;
5389  struct CryptKeyInfo *results = NULL, *k = NULL;
5390  struct CryptKeyInfo **kend = NULL;
5391  struct CryptKeyInfo *choice = NULL;
5392 
5393  gpgme_ctx_t ctx = create_gpgme_context(false);
5394 
5395  /* list all secret keys */
5396  if (gpgme_op_keylist_start(ctx, NULL, 1))
5397  goto cleanup;
5398 
5399  kend = &results;
5400 
5401  while (!(err = gpgme_op_keylist_next(ctx, &key)))
5402  {
5404 
5406  flags |= KEYFLAG_CANENCRYPT;
5407  if (key_check_cap(key, KEY_CAP_CAN_SIGN))
5408  flags |= KEYFLAG_CANSIGN;
5409 
5410  if (key->revoked)
5411  flags |= KEYFLAG_REVOKED;
5412  if (key->expired)
5413  flags |= KEYFLAG_EXPIRED;
5414  if (key->disabled)
5415  flags |= KEYFLAG_DISABLED;
5416 
5417  int idx;
5418  for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
5419  {
5420  k = mutt_mem_calloc(1, sizeof(*k));
5421  k->kobj = key;
5422  gpgme_key_ref(k->kobj);
5423  k->idx = idx;
5424  k->uid = uid->uid;
5425  k->flags = flags;
5426  if (uid->revoked)
5427  k->flags |= KEYFLAG_REVOKED;
5428  k->validity = uid->validity;
5429  *kend = k;
5430  kend = &k->next;
5431  }
5432  gpgme_key_unref(key);
5433  }
5434  if (gpg_err_code(err) != GPG_ERR_EOF)
5435  mutt_error(_("gpgme_op_keylist_next failed: %s"), gpgme_strerror(err));
5436  gpgme_op_keylist_end(ctx);
5437 
5438  if (!results)
5439  {
5440  /* L10N:
5441  mutt_gpgme_select_secret_key() tries to list all secret keys to choose
5442  from. This error is displayed if no results were found.
5443  */
5444  mutt_error(_("No secret keys found"));
5445  goto cleanup;
5446  }
5447 
5448  choice = crypt_select_key(results, NULL, "*", APPLICATION_PGP, &junk);
5449  if (!(choice && choice->kobj && choice->kobj->subkeys && choice->kobj->subkeys->fpr))
5450  goto cleanup;
5451  mutt_buffer_strcpy(keyid, choice->kobj->subkeys->fpr);
5452 
5453  rc = 0;
5454 
5455 cleanup:
5456  crypt_key_free(&choice);
5457  crypt_key_free(&results);
5458  gpgme_release(ctx);
5459  return rc;
5460 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
static void crypt_key_free(struct CryptKeyInfo **keylist)
Release all the keys in a list.
Definition: crypt_gpgme.c:639
static struct CryptKeyInfo * crypt_select_key(struct CryptKeyInfo *keys, struct Address *p, const char *s, unsigned int app, int *forced_valid)
Get the user to select a key.
Definition: crypt_gpgme.c:4711
#define _(a)
Definition: message.h:28
struct CryptKeyInfo * next
Definition: crypt_gpgme.c:121
#define KEYFLAG_CANENCRYPT
Key is suitable for encryption.
Definition: lib.h:173
A stored PGP key.
Definition: crypt_gpgme.c:119
int idx
and the user ID at this index
Definition: crypt_gpgme.c:123
static gpgme_ctx_t create_gpgme_context(bool for_smime)
Create a new GPGME context.
Definition: crypt_gpgme.c:760
#define KEYFLAG_EXPIRED
Key is expired.
Definition: lib.h:176
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:135
#define KEYFLAG_NO_FLAGS
No flags are set.
Definition: lib.h:171
uint16_t KeyFlags
Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN.
Definition: lib.h:170
gpgme_key_t kobj
Definition: crypt_gpgme.c:122
Key can be used for signing.
Definition: crypt_gpgme.c:157
#define KEYFLAG_DISABLED
Key is marked disabled.
Definition: lib.h:178
#define KEYFLAG_CANSIGN
Key is suitable for signing.
Definition: lib.h:172
Key can be used for encryption.
Definition: crypt_gpgme.c:156
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
KeyFlags flags
global and per uid flags (for convenience)
Definition: crypt_gpgme.c:125
#define mutt_error(...)
Definition: logging.h:84
#define KEYFLAG_REVOKED
Key is revoked.
Definition: lib.h:177
static unsigned int key_check_cap(gpgme_key_t key, enum KeyCap cap)
Check the capabilities of a key.
Definition: crypt_gpgme.c:4104
+ Here is the call graph for this function:
+ Here is the caller graph for this function: