Skip to content

HTTPS clone URL

Subversion checkout URL

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