Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 892 lines (713 sloc) 21.195 kB
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
1 /*
e8da501 Fix Mike's and my e-mail addresses in copyright lines.
Thomas Roessler authored
2 * Copyright (C) 1996,1997 Michael R. Elkins <me@mutt.org>
3 * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org>
4 * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
5 * Oliver Ehli <elmy@acm.org>
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
6 * Copyright (C) 2003 Werner Koch <wk@gnupg.org>
cd320dc This is the sequel to the crypto modularization changes I did on
Moritz Schulte authored
7 * Copyright (C) 2004 g10code GmbH
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 */
23
bd77e36 @bcully Add config.h to the top of every C file that could possibly want it.
bcully authored
24 #if HAVE_CONFIG_H
25 # include "config.h"
26 #endif
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
27
28 #include "mutt.h"
29 #include "mutt_curses.h"
30 #include "mime.h"
31 #include "copy.h"
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
32 #include "mutt_crypt.h"
d3d728d Don't use functions without importing the corresponding prototype.
Thomas Roessler authored
33 #include "pgp.h"
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
34
35 #include <sys/wait.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <sys/stat.h>
40 #include <errno.h>
41 #include <ctype.h>
42
43 #ifdef HAVE_LOCALE_H
44 #include <locale.h>
45 #endif
46
47 #ifdef HAVE_SYS_TIME_H
48 # include <sys/time.h>
49 #endif
50
51 #ifdef HAVE_SYS_RESOURCE_H
52 # include <sys/resource.h>
53 #endif
54
55
56 /* print the current time to avoid spoofing of the signature output */
57 void crypt_current_time(STATE *s, char *app_name)
58 {
59 time_t t;
60 char p[STRING], tmp[STRING];
61
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
62 if (!WithCrypto)
63 return;
64
5bf1a6a Add a new crypt_timestamp option. The timestamps aren't really
Thomas Roessler authored
65 if (option (OPTCRYPTTIMESTAMP))
66 {
67 t = time(NULL);
68 setlocale (LC_TIME, "");
69 strftime (p, sizeof (p), _(" (current time: %c)"), localtime (&t));
70 setlocale (LC_TIME, "C");
71 }
72 else
73 *p = '\0';
74
75 snprintf (tmp, sizeof (tmp), _("[-- %s output follows%s --]\n"), NONULL(app_name), p);
76 state_attach_puts (tmp, s);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
77 }
78
79
80
81 void crypt_forget_passphrase (void)
82 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
83 if ((WithCrypto & APPLICATION_PGP))
84 crypt_pgp_void_passphrase ();
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
85
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
86 if ((WithCrypto & APPLICATION_SMIME))
87 crypt_smime_void_passphrase ();
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
88
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
89 if (WithCrypto)
90 mutt_message _("Passphrase(s) forgotten.");
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
91 }
92
93
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
94 #if defined(HAVE_SETRLIMIT) && (!defined(DEBUG))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
95
96 static void disable_coredumps (void)
97 {
98 struct rlimit rl = {0, 0};
99 static short done = 0;
100
101 if (!done)
102 {
103 setrlimit (RLIMIT_CORE, &rl);
104 done = 1;
105 }
106 }
107
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
108 #endif /* HAVE_SETRLIMIT */
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
109
110
111 int crypt_valid_passphrase(int flags)
112 {
cd320dc This is the sequel to the crypto modularization changes I did on
Moritz Schulte authored
113 int ret = 0;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
114
115 # if defined(HAVE_SETRLIMIT) &&(!defined(DEBUG))
116 disable_coredumps ();
117 # endif
118
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
119 if ((WithCrypto & APPLICATION_PGP) && (flags & APPLICATION_PGP))
cd320dc This is the sequel to the crypto modularization changes I did on
Moritz Schulte authored
120 ret = crypt_pgp_valid_passphrase ();
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
121
122 if ((WithCrypto & APPLICATION_SMIME) && (flags & APPLICATION_SMIME))
cd320dc This is the sequel to the crypto modularization changes I did on
Moritz Schulte authored
123 ret = crypt_smime_valid_passphrase ();
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
124
cd320dc This is the sequel to the crypto modularization changes I did on
Moritz Schulte authored
125 return ret;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
126 }
127
128
129
d212c82 See: http://does-not-exist.org/mail-archives/mutt-dev/msg00843.html
Dale Woolridge authored
130 int mutt_protect (HEADER *msg, char *keylist)
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
131 {
132 BODY *pbody = NULL, *tmp_pbody = NULL;
133 BODY *tmp_smime_pbody = NULL;
134 BODY *tmp_pgp_pbody = NULL;
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
135 int flags = (WithCrypto & APPLICATION_PGP)? msg->security: 0;
136 int i;
137
138 if (!WithCrypto)
139 return -1;
140
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
141 if ((msg->security & SIGN) && !crypt_valid_passphrase (msg->security))
142 return (-1);
143
d212c82 See: http://does-not-exist.org/mail-archives/mutt-dev/msg00843.html
Dale Woolridge authored
144 if ((WithCrypto & APPLICATION_PGP) && ((msg->security & PGPINLINE) == PGPINLINE))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
145 {
d212c82 See: http://does-not-exist.org/mail-archives/mutt-dev/msg00843.html
Dale Woolridge authored
146 /* they really want to send it inline... go for it */
147 if (!isendwin ()) mutt_endwin _("Invoking PGP...");
148 pbody = crypt_pgp_traditional_encryptsign (msg->content, flags, keylist);
149 if (pbody)
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
150 {
151 msg->content = pbody;
152 return 0;
153 }
d212c82 See: http://does-not-exist.org/mail-archives/mutt-dev/msg00843.html
Dale Woolridge authored
154
155 /* otherwise inline won't work...ask for revert */
421e10f @dmshaw Rename pgp_mime_ask to pgp_mime_auto; change the default; change the
dmshaw authored
156 if ((i = query_quadoption (OPT_PGPMIMEAUTO, _("Message can't be sent inline. Revert to using PGP/MIME?"))) != M_YES)
157 {
158 mutt_error _("Mail not sent.");
159 return -1;
160 }
d212c82 See: http://does-not-exist.org/mail-archives/mutt-dev/msg00843.html
Dale Woolridge authored
161
162 /* go ahead with PGP/MIME */
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
163 }
164
165 if (!isendwin ()) mutt_endwin (NULL);
166
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
167 if ((WithCrypto & APPLICATION_SMIME))
168 tmp_smime_pbody = msg->content;
6015e8a Retainable PGP signatures were broken badly. #1757.
Thomas Roessler authored
169 if ((WithCrypto & APPLICATION_PGP))
170 tmp_pgp_pbody = msg->content;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
171
172 if (msg->security & SIGN)
173 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
174 if ((WithCrypto & APPLICATION_SMIME)
175 && (msg->security & APPLICATION_SMIME))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
176 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
177 if (!(tmp_pbody = crypt_smime_sign_message (msg->content)))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
178 return -1;
179 pbody = tmp_smime_pbody = tmp_pbody;
180 }
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
181
182 if ((WithCrypto & APPLICATION_PGP)
183 && (msg->security & APPLICATION_PGP)
184 && (!(flags & ENCRYPT) || option (OPTPGPRETAINABLESIG)))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
185 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
186 if (!(tmp_pbody = crypt_pgp_sign_message (msg->content)))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
187 return -1;
188
189 flags &= ~SIGN;
190 pbody = tmp_pgp_pbody = tmp_pbody;
191 }
192
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
193 if (WithCrypto
194 && (msg->security & APPLICATION_SMIME)
195 && (msg->security & APPLICATION_PGP))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
196 {
197 /* here comes the draft ;-) */
198 }
199 }
200
201
202 if (msg->security & ENCRYPT)
203 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
204 if ((WithCrypto & APPLICATION_SMIME)
205 && (msg->security & APPLICATION_SMIME))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
206 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
207 if (!(tmp_pbody = crypt_smime_build_smime_entity (tmp_smime_pbody,
208 keylist)))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
209 {
210 /* signed ? free it! */
211 return (-1);
212 }
213 /* free tmp_body if messages was signed AND encrypted ... */
214 if (tmp_smime_pbody != msg->content && tmp_smime_pbody != tmp_pbody)
215 {
216 /* detatch and dont't delete msg->content,
217 which tmp_smime_pbody->parts after signing. */
218 tmp_smime_pbody->parts = tmp_smime_pbody->parts->next;
219 msg->content->next = NULL;
220 mutt_free_body (&tmp_smime_pbody);
221 }
222 pbody = tmp_pbody;
223 }
224
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
225 if ((WithCrypto & APPLICATION_PGP)
226 && (msg->security & APPLICATION_PGP))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
227 {
6015e8a Retainable PGP signatures were broken badly. #1757.
Thomas Roessler authored
228 if (!(pbody = crypt_pgp_encrypt_message (tmp_pgp_pbody, keylist,
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
229 flags & SIGN)))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
230 {
231
232 /* did we perform a retainable signature? */
233 if (flags != msg->security)
234 {
235 /* remove the outer multipart layer */
6015e8a Retainable PGP signatures were broken badly. #1757.
Thomas Roessler authored
236 tmp_pgp_pbody = mutt_remove_multipart (tmp_pgp_pbody);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
237 /* get rid of the signature */
6015e8a Retainable PGP signatures were broken badly. #1757.
Thomas Roessler authored
238 mutt_free_body (&tmp_pgp_pbody->next);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
239 }
240
241 return (-1);
242 }
243
244 /* destroy temporary signature envelope when doing retainable
245 * signatures.
cd320dc This is the sequel to the crypto modularization changes I did on
Moritz Schulte authored
246
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
247 */
248 if (flags != msg->security)
249 {
6015e8a Retainable PGP signatures were broken badly. #1757.
Thomas Roessler authored
250 tmp_pgp_pbody = mutt_remove_multipart (tmp_pgp_pbody);
251 mutt_free_body (&tmp_pgp_pbody->next);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
252 }
253 }
254 }
255
256 if(pbody)
257 msg->content = pbody;
258
259 return 0;
260 }
261
262
263
264
265 int mutt_is_multipart_signed (BODY *b)
266 {
267 char *p;
268
269 if (!b || !(b->type == TYPEMULTIPART) ||
6bb1341 Fix S/MIME signature type. Noted by Dan Ohnesorg <Dan@ohnesorg.cz>.
Thomas Roessler authored
270 !b->subtype || ascii_strcasecmp(b->subtype, "signed"))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
271 return 0;
272
273 if (!(p = mutt_get_parameter("protocol", b->parameter)))
274 return 0;
275
6bb1341 Fix S/MIME signature type. Noted by Dan Ohnesorg <Dan@ohnesorg.cz>.
Thomas Roessler authored
276 if (!(ascii_strcasecmp (p, "multipart/mixed")))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
277 return SIGN;
278
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
279 if ((WithCrypto & APPLICATION_PGP)
280 && !(ascii_strcasecmp (p, "application/pgp-signature")))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
281 return PGPSIGN;
282
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
283 if ((WithCrypto & APPLICATION_SMIME)
284 && !(ascii_strcasecmp (p, "application/x-pkcs7-signature")))
6bb1341 Fix S/MIME signature type. Noted by Dan Ohnesorg <Dan@ohnesorg.cz>.
Thomas Roessler authored
285 return SMIMESIGN;
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
286 if ((WithCrypto & APPLICATION_SMIME)
287 && !(ascii_strcasecmp (p, "application/pkcs7-signature")))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
288 return SMIMESIGN;
289
290 return 0;
291 }
292
293
294 int mutt_is_multipart_encrypted (BODY *b)
295 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
296 if ((WithCrypto & APPLICATION_PGP))
297 {
298 char *p;
299
300 if (!b || b->type != TYPEMULTIPART ||
301 !b->subtype || ascii_strcasecmp (b->subtype, "encrypted") ||
302 !(p = mutt_get_parameter ("protocol", b->parameter)) ||
303 ascii_strcasecmp (p, "application/pgp-encrypted"))
304 return 0;
305
306 return PGPENCRYPT;
307 }
308
309 return 0;
310 }
311
312
313 int mutt_is_application_pgp (BODY *m)
314 {
315 int t = 0;
316 char *p;
317
318 if (m->type == TYPEAPPLICATION)
319 {
320 if (!ascii_strcasecmp (m->subtype, "pgp") || !ascii_strcasecmp (m->subtype, "x-pgp-message"))
321 {
322 if ((p = mutt_get_parameter ("x-action", m->parameter))
323 && (!ascii_strcasecmp (p, "sign") || !ascii_strcasecmp (p, "signclear")))
324 t |= PGPSIGN;
325
326 if ((p = mutt_get_parameter ("format", m->parameter)) &&
327 !ascii_strcasecmp (p, "keys-only"))
328 t |= PGPKEY;
329
330 if(!t) t |= PGPENCRYPT; /* not necessarily correct, but... */
331 }
332
333 if (!ascii_strcasecmp (m->subtype, "pgp-signed"))
334 t |= PGPSIGN;
335
336 if (!ascii_strcasecmp (m->subtype, "pgp-keys"))
337 t |= PGPKEY;
338 }
339 else if (m->type == TYPETEXT && ascii_strcasecmp ("plain", m->subtype) == 0)
340 {
341 if (((p = mutt_get_parameter ("x-mutt-action", m->parameter))
342 || (p = mutt_get_parameter ("x-action", m->parameter))
343 || (p = mutt_get_parameter ("action", m->parameter)))
344 && !ascii_strncasecmp ("pgp-sign", p, 8))
345 t |= PGPSIGN;
346 else if (p && !ascii_strncasecmp ("pgp-encrypt", p, 11))
347 t |= PGPENCRYPT;
348 else if (p && !ascii_strncasecmp ("pgp-keys", p, 7))
349 t |= PGPKEY;
350 }
d212c82 See: http://does-not-exist.org/mail-archives/mutt-dev/msg00843.html
Dale Woolridge authored
351 if (t)
352 t |= PGPINLINE;
353
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
354 return t;
355 }
356
357 int mutt_is_application_smime (BODY *m)
358 {
359 char *t=NULL;
360 int len, complain=0;
361
d22f335 The attached patch fixes a segfault I observed today: mutt failed to
Christoph Ludwig authored
362 if(!m)
363 return 0;
364
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
365 if ((m->type & TYPEAPPLICATION) && m->subtype)
366 {
367 /* S/MIME MIME types don't need x- anymore, see RFC2311 */
368 if (!ascii_strcasecmp (m->subtype, "x-pkcs7-mime") ||
369 !ascii_strcasecmp (m->subtype, "pkcs7-mime"))
370 {
371 if ((t = mutt_get_parameter ("smime-type", m->parameter)))
372 {
373 if (!ascii_strcasecmp (t, "enveloped-data"))
374 return SMIMEENCRYPT;
375 else if (!ascii_strcasecmp (t, "signed-data"))
376 return (SMIMESIGN|SMIMEOPAQUE);
377 else return 0;
378 }
379 /* Netscape 4.7 uses
380 * Content-Description: S/MIME Encrypted Message
381 * instead of Content-Type parameter
382 */
383 if (!ascii_strcasecmp (m->description, "S/MIME Encrypted Message"))
384 return SMIMEENCRYPT;
385 complain = 1;
386 }
387 else if (ascii_strcasecmp (m->subtype, "octet-stream"))
388 return 0;
389
390 t = mutt_get_parameter ("name", m->parameter);
391
392 if (!t) t = m->d_filename;
393 if (!t) t = m->filename;
394 if (!t)
395 {
396 if (complain)
397 mutt_message (_("S/MIME messages with no hints on content are unsupported."));
398 return 0;
399 }
400
401 /* no .p7c, .p10 support yet. */
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
402
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
403 len = mutt_strlen (t) - 4;
404 if (len > 0 && *(t+len) == '.')
405 {
406 len++;
407 if (!ascii_strcasecmp ((t+len), "p7m"))
408 #if 0
409 return SMIMEENCRYPT;
410 #else
411 /* Not sure if this is the correct thing to do, but
412 it's required for compatibility with Outlook */
413 return (SMIMESIGN|SMIMEOPAQUE);
414 #endif
415 else if (!ascii_strcasecmp ((t+len), "p7s"))
416 return (SMIMESIGN|SMIMEOPAQUE);
417 }
418 }
419
420 return 0;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
421 }
422
423
424
425
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
426
427
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
428 int crypt_query (BODY *m)
429 {
430 int t = 0;
431
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
432 if (!WithCrypto)
433 return 0;
3b9a36e Handle partially signed messages more reasonably. See #1743.
Thomas Roessler authored
434
435 if (!m)
436 return 0;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
437
438 if (m->type == TYPEAPPLICATION)
439 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
440 if ((WithCrypto & APPLICATION_PGP))
441 t |= mutt_is_application_pgp(m);
442
443 if ((WithCrypto & APPLICATION_SMIME))
444 {
445 t |= mutt_is_application_smime(m);
446 if (t && m->goodsig) t |= GOODSIGN;
447 if (t && m->badsig) t |= BADSIGN;
448 }
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
449 }
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
450 else if ((WithCrypto & APPLICATION_PGP) && m->type == TYPETEXT)
3654574 More inline PGP changes.
Thomas Roessler authored
451 {
9c675b1 OK, I'm giving up: pgp_create_traditional now creates text/plain;
Thomas Roessler authored
452 t |= mutt_is_application_pgp (m);
3654574 More inline PGP changes.
Thomas Roessler authored
453 if (t && m->goodsig)
454 t |= GOODSIGN;
455 }
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
456
457 if (m->type == TYPEMULTIPART)
458 {
459 t |= mutt_is_multipart_encrypted(m);
460 t |= mutt_is_multipart_signed (m);
461
3b9a36e Handle partially signed messages more reasonably. See #1743.
Thomas Roessler authored
462 if (t && m->goodsig)
463 t |= GOODSIGN;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
464 }
465
466 if (m->type == TYPEMULTIPART || m->type == TYPEMESSAGE)
467 {
468 BODY *p;
3b9a36e Handle partially signed messages more reasonably. See #1743.
Thomas Roessler authored
469 int u, v, w;
470
471 u = m->parts ? 0xffffffff : 0; /* Bits set in all parts */
472 w = 0; /* Bits set in any part */
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
473
474 for (p = m->parts; p; p = p->next)
3b9a36e Handle partially signed messages more reasonably. See #1743.
Thomas Roessler authored
475 {
476 v = crypt_query (p);
477 u &= v; w |= v;
478 }
479 t |= u | (w & ~GOODSIGN);
480
481 if ((w & GOODSIGN) && !(u & GOODSIGN))
482 t |= PARTSIGN;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
483 }
484
485 return t;
486 }
487
488
489
490
491 int crypt_write_signed(BODY *a, STATE *s, const char *tempfile)
492 {
493 FILE *fp;
494 int c;
495 short hadcr;
496 size_t bytes;
497
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
498 if (!WithCrypto)
499 return -1;
500
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
501 if (!(fp = safe_fopen (tempfile, "w")))
502 {
503 mutt_perror (tempfile);
504 return -1;
505 }
506
507 fseek (s->fpin, a->hdr_offset, 0);
508 bytes = a->length + a->offset - a->hdr_offset;
509 hadcr = 0;
510 while (bytes > 0)
511 {
512 if ((c = fgetc (s->fpin)) == EOF)
513 break;
514
515 bytes--;
516
517 if (c == '\r')
518 hadcr = 1;
519 else
520 {
521 if (c == '\n' && !hadcr)
522 fputc ('\r', fp);
523
524 hadcr = 0;
525 }
526
527 fputc (c, fp);
528
529 }
530 fclose (fp);
531
532 return 0;
533 }
534
535
536
537 void convert_to_7bit (BODY *a)
538 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
539 if (!WithCrypto)
540 return;
541
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
542 while (a)
543 {
544 if (a->type == TYPEMULTIPART)
545 {
546 if (a->encoding != ENC7BIT)
547 {
548 a->encoding = ENC7BIT;
549 convert_to_7bit(a->parts);
550 }
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
551 else if ((WithCrypto & APPLICATION_PGP) && option (OPTPGPSTRICTENC))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
552 convert_to_7bit (a->parts);
553 }
554 else if (a->type == TYPEMESSAGE &&
555 mutt_strcasecmp(a->subtype, "delivery-status"))
556 {
557 if(a->encoding != ENC7BIT)
558 mutt_message_to_7bit (a, NULL);
559 }
560 else if (a->encoding == ENC8BIT)
561 a->encoding = ENCQUOTEDPRINTABLE;
562 else if (a->encoding == ENCBINARY)
563 a->encoding = ENCBASE64;
564 else if (a->content && a->encoding != ENCBASE64 &&
565 (a->content->from || (a->content->space &&
566 option (OPTPGPSTRICTENC))))
567 a->encoding = ENCQUOTEDPRINTABLE;
568 a = a->next;
569 }
570 }
571
572
573
574
575 void crypt_extract_keys_from_messages (HEADER * h)
576 {
577 int i;
578 char tempfname[_POSIX_PATH_MAX], *mbox;
579 ADDRESS *tmp = NULL;
580 FILE *fpout;
581
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
582 if (!WithCrypto)
583 return;
584
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
585 mutt_mktemp (tempfname);
586 if (!(fpout = safe_fopen (tempfname, "w")))
587 {
588 mutt_perror (tempfname);
589 return;
590 }
591
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
592 if ((WithCrypto & APPLICATION_PGP))
593 set_option (OPTDONTHANDLEPGPKEYS);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
594
595 if (!h)
596 {
597 for (i = 0; i < Context->vcount; i++)
598 {
599 if (Context->hdrs[Context->v2r[i]]->tagged)
600 {
601 mutt_parse_mime_message (Context, Context->hdrs[Context->v2r[i]]);
602 if (Context->hdrs[Context->v2r[i]]->security & ENCRYPT &&
603 !crypt_valid_passphrase (Context->hdrs[Context->v2r[i]]->security))
604 {
605 fclose (fpout);
606 break;
607 }
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
608
609 if ((WithCrypto & APPLICATION_PGP)
610 && (Context->hdrs[Context->v2r[i]]->security & APPLICATION_PGP))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
611 {
612 mutt_copy_message (fpout, Context, Context->hdrs[Context->v2r[i]],
613 M_CM_DECODE|M_CM_CHARCONV, 0);
614 fflush(fpout);
615
616 mutt_endwin (_("Trying to extract PGP keys...\n"));
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
617 crypt_pgp_invoke_import (tempfname);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
618 }
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
619
620 if ((WithCrypto & APPLICATION_SMIME)
621 && (Context->hdrs[Context->v2r[i]]->security & APPLICATION_SMIME))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
622 {
623 if (Context->hdrs[Context->v2r[i]]->security & ENCRYPT)
624 mutt_copy_message (fpout, Context, Context->hdrs[Context->v2r[i]],
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
625 M_CM_NOHEADER|M_CM_DECODE_CRYPT
626 |M_CM_DECODE_SMIME, 0);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
627 else
628 mutt_copy_message (fpout, Context,
629 Context->hdrs[Context->v2r[i]], 0, 0);
630 fflush(fpout);
631
632 if (Context->hdrs[Context->v2r[i]]->env->from)
633 tmp = mutt_expand_aliases (h->env->from);
634 else if (Context->hdrs[Context->v2r[i]]->env->sender)
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
635 tmp = mutt_expand_aliases (Context->hdrs[Context->v2r[i]]
636 ->env->sender);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
637 mbox = tmp ? tmp->mailbox : NULL;
638 if (mbox)
639 {
f9bf013 Some S/MIME fixes from Oliver Ehli <elmy@acm.org>.
Thomas Roessler authored
640 mutt_endwin (_("Trying to extract S/MIME certificates...\n"));
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
641 crypt_smime_invoke_import (tempfname, mbox);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
642 tmp = NULL;
643 }
644 }
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
645
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
646 rewind (fpout);
647 }
648 }
649 }
650 else
651 {
652 mutt_parse_mime_message (Context, h);
653 if (!(h->security & ENCRYPT && !crypt_valid_passphrase (h->security)))
654 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
655 if ((WithCrypto & APPLICATION_PGP)
656 && (h->security & APPLICATION_PGP))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
657 {
658 mutt_copy_message (fpout, Context, h, M_CM_DECODE|M_CM_CHARCONV, 0);
659 fflush(fpout);
fee341b S/MIME nits.
Thomas Roessler authored
660 mutt_endwin (_("Trying to extract PGP keys...\n"));
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
661 crypt_pgp_invoke_import (tempfname);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
662 }
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
663
664 if ((WithCrypto & APPLICATION_SMIME)
665 && (h->security & APPLICATION_SMIME))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
666 {
667 if (h->security & ENCRYPT)
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
668 mutt_copy_message (fpout, Context, h, M_CM_NOHEADER
669 |M_CM_DECODE_CRYPT
670 |M_CM_DECODE_SMIME, 0);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
671 else
672 mutt_copy_message (fpout, Context, h, 0, 0);
673
674 fflush(fpout);
675 if (h->env->from) tmp = mutt_expand_aliases (h->env->from);
676 else if (h->env->sender) tmp = mutt_expand_aliases (h->env->sender);
677 mbox = tmp ? tmp->mailbox : NULL;
678 if (mbox) /* else ? */
679 {
680 mutt_message (_("Trying to extract S/MIME certificates...\n"));
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
681 crypt_smime_invoke_import (tempfname, mbox);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
682 }
683 }
684 }
685 }
686
687 fclose (fpout);
3a347e9 More S/MIME nit-picking.
Thomas Roessler authored
688 if (isendwin())
689 mutt_any_key_to_continue (NULL);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
690
691 mutt_unlink (tempfname);
692
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
693 if ((WithCrypto & APPLICATION_PGP))
694 unset_option (OPTDONTHANDLEPGPKEYS);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
695 }
696
697
698
699 int crypt_get_keys (HEADER *msg, char **keylist)
700 {
701 /* Do a quick check to make sure that we can find all of the encryption
702 * keys if the user has requested this service.
703 */
704
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
705 if (!WithCrypto)
706 return 0;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
707
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
708 if ((WithCrypto & APPLICATION_PGP))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
709 set_option (OPTPGPCHECKTRUST);
710
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
711 *keylist = NULL;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
712
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
713 if (msg->security & ENCRYPT)
714 {
715 if ((WithCrypto & APPLICATION_PGP)
716 && (msg->security & APPLICATION_PGP))
717 {
718 if ((*keylist = crypt_pgp_findkeys (msg->env->to, msg->env->cc,
719 msg->env->bcc)) == NULL)
720 return (-1);
721 unset_option (OPTPGPCHECKTRUST);
722 }
723 if ((WithCrypto & APPLICATION_SMIME)
724 && (msg->security & APPLICATION_SMIME))
725 {
726 if ((*keylist = crypt_smime_findkeys (msg->env->to, msg->env->cc,
727 msg->env->bcc)) == NULL)
728 return (-1);
729 }
730 }
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
731
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
732 return (0);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
733 }
734
735
736
737 static void crypt_fetch_signatures (BODY ***signatures, BODY *a, int *n)
738 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
739 if (!WithCrypto)
740 return;
741
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
742 for (; a; a = a->next)
743 {
744 if (a->type == TYPEMULTIPART)
745 crypt_fetch_signatures (signatures, a->parts, n);
746 else
747 {
748 if((*n % 5) == 0)
0be4889 As the ones of you who compile with new gcc's probably have noticed,
Mads Martin Joergensen authored
749 safe_realloc (signatures, (*n + 6) * sizeof (BODY **));
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
750
751 (*signatures)[(*n)++] = a;
752 }
753 }
754 }
755
756
757 /*
758 * This routine verifies a "multipart/signed" body.
759 */
760
ca2fc2b @bcully Add error results to mutt_body_handlers, and check them when doing
bcully authored
761 int mutt_signed_handler (BODY *a, STATE *s)
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
762 {
763 char tempfile[_POSIX_PATH_MAX];
764 char *protocol;
765 int protocol_major = TYPEOTHER;
766 char *protocol_minor = NULL;
767
768 BODY *b = a;
769 BODY **signatures = NULL;
770 int sigcnt = 0;
771 int i;
772 short goodsig = 1;
ca2fc2b @bcully Add error results to mutt_body_handlers, and check them when doing
bcully authored
773 int rc = 0;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
774
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
775 if (!WithCrypto)
ca2fc2b @bcully Add error results to mutt_body_handlers, and check them when doing
bcully authored
776 return -1;
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
777
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
778 protocol = mutt_get_parameter ("protocol", a->parameter);
779 a = a->parts;
780
781 /* extract the protocol information */
782
783 if (protocol)
784 {
785 char major[STRING];
786 char *t;
787
788 if ((protocol_minor = strchr (protocol, '/'))) protocol_minor++;
789
790 strfcpy (major, protocol, sizeof(major));
791 if((t = strchr(major, '/')))
792 *t = '\0';
793
794 protocol_major = mutt_check_mime_type (major);
795 }
796
797 /* consistency check */
798
799 if (!(a && a->next && a->next->type == protocol_major &&
800 !mutt_strcasecmp (a->next->subtype, protocol_minor)))
801 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
802 state_attach_puts (_("[-- Error: "
803 "Inconsistent multipart/signed structure! --]\n\n"),
804 s);
ca2fc2b @bcully Add error results to mutt_body_handlers, and check them when doing
bcully authored
805 return mutt_body_handler (a, s);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
806 }
807
808
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
809 if ((WithCrypto & APPLICATION_PGP)
810 && protocol_major == TYPEAPPLICATION
811 && !mutt_strcasecmp (protocol_minor, "pgp-signature"))
812 ;
813 else if ((WithCrypto & APPLICATION_SMIME)
814 && protocol_major == TYPEAPPLICATION
c719634 Fix #1486; noted by Jeroen Coekaerts <jeroen@coekaerts.be>.
Thomas Roessler authored
815 && !(mutt_strcasecmp (protocol_minor, "x-pkcs7-signature")
dd52a62 I should test-compile things before committing. Stupid typo.
Thomas Roessler authored
816 && mutt_strcasecmp (protocol_minor, "pkcs7-signature")))
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
817 ;
818 else if (protocol_major == TYPEMULTIPART
819 && !mutt_strcasecmp (protocol_minor, "mixed"))
820 ;
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
821 else
822 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
823 state_printf (s, _("[-- Error: "
824 "Unknown multipart/signed protocol %s! --]\n\n"),
825 protocol);
ca2fc2b @bcully Add error results to mutt_body_handlers, and check them when doing
bcully authored
826 return mutt_body_handler (a, s);
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
827 }
828
829 if (s->flags & M_DISPLAY)
830 {
831
832 crypt_fetch_signatures (&signatures, a->next, &sigcnt);
833
834 if (sigcnt)
835 {
836 mutt_mktemp (tempfile);
837 if (crypt_write_signed (a, s, tempfile) == 0)
838 {
839 for (i = 0; i < sigcnt; i++)
840 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
841 if ((WithCrypto & APPLICATION_PGP)
842 && signatures[i]->type == TYPEAPPLICATION
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
843 && !mutt_strcasecmp (signatures[i]->subtype, "pgp-signature"))
844 {
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
845 if (crypt_pgp_verify_one (signatures[i], s, tempfile) != 0)
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
846 goodsig = 0;
847
848 continue;
849 }
4d4634a - To cleanup the pgp/smime code and prepare for other backends.
Werner Koch authored
850
851 if ((WithCrypto & APPLICATION_SMIME)
852 && signatures[i]->type == TYPEAPPLICATION
d7cc75f pkcs7-signature wasn't recognized properly in one more place.
Scott Koranda authored
853 && (!mutt_strcasecmp(signatures[i]->subtype, "x-pkcs7-signature")
854 || !mutt_strcasecmp(signatures[i]->subtype, "pkcs7-signature")))
8fa3b30 S/MIME support. From Oliver Ehli <elmy@acm.org> and Mike Schiraldi
Thomas Roessler authored
855 {
4d4634a