mutt stable branch with some hacks
1/*
2 * Copyright (C) 2003 Werner Koch <wk@gnupg.org>
3 * Copyright (C) 2004 g10 Code GmbH
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20/*
21 This file dispatches the generic crypto functions to the
22 implemented backend or provides dummy stubs. Note, that some
23 generic functions are handled in crypt.c.
24*/
25
26/* Note: This file has been changed to make use of the new module
27 system. Consequently there's a 1:1 mapping between the functions
28 contained in this file and the functions implemented by the crypto
29 modules. */
30
31#if HAVE_CONFIG_H
32# include "config.h"
33#endif
34
35#include "mutt.h"
36#include "mutt_crypt.h"
37
38#include "crypt-mod.h"
39
40#ifdef USE_AUTOCRYPT
41#include "autocrypt.h"
42#endif
43
44/*
45
46 Generic
47
48*/
49
50#ifdef CRYPT_BACKEND_CLASSIC_PGP
51extern struct crypt_module_specs crypt_mod_pgp_classic;
52#endif
53
54#ifdef CRYPT_BACKEND_CLASSIC_SMIME
55extern struct crypt_module_specs crypt_mod_smime_classic;
56#endif
57
58#ifdef CRYPT_BACKEND_GPGME
59#include "crypt-gpgme.h"
60extern struct crypt_module_specs crypt_mod_pgp_gpgme;
61extern struct crypt_module_specs crypt_mod_smime_gpgme;
62#endif
63
64void crypt_init (void)
65{
66#ifdef CRYPT_BACKEND_CLASSIC_PGP
67 if (
68#ifdef CRYPT_BACKEND_GPGME
69 (! option (OPTCRYPTUSEGPGME))
70#else
71 1
72#endif
73 )
74 crypto_module_register (&crypt_mod_pgp_classic);
75#endif
76
77#ifdef CRYPT_BACKEND_CLASSIC_SMIME
78 if (
79#ifdef CRYPT_BACKEND_GPGME
80 (! option (OPTCRYPTUSEGPGME))
81#else
82 1
83#endif
84 )
85 crypto_module_register (&crypt_mod_smime_classic);
86#endif
87
88 if (option (OPTCRYPTUSEGPGME))
89 {
90#ifdef CRYPT_BACKEND_GPGME
91 crypto_module_register (&crypt_mod_pgp_gpgme);
92 crypto_module_register (&crypt_mod_smime_gpgme);
93#else
94 mutt_message (_("\"crypt_use_gpgme\" set"
95 " but not built with GPGME support."));
96 if (mutt_any_key_to_continue (NULL) == -1)
97 mutt_exit(1);
98#endif
99 }
100
101#if defined CRYPT_BACKEND_CLASSIC_PGP || defined CRYPT_BACKEND_CLASSIC_SMIME || defined CRYPT_BACKEND_GPGME
102 if (CRYPT_MOD_CALL_CHECK (PGP, init))
103 (CRYPT_MOD_CALL (PGP, init)) ();
104
105 if (CRYPT_MOD_CALL_CHECK (SMIME, init))
106 (CRYPT_MOD_CALL (SMIME, init)) ();
107#endif
108}
109
110
111/* Show a message that a backend will be invoked. */
112void crypt_invoke_message (int type)
113{
114 if ((WithCrypto & APPLICATION_PGP) && (type & APPLICATION_PGP))
115 mutt_message _("Invoking PGP...");
116 else if ((WithCrypto & APPLICATION_SMIME) && (type & APPLICATION_SMIME))
117 mutt_message _("Invoking S/MIME...");
118}
119
120/* Returns 1 if a module backend is registered for the type */
121int crypt_has_module_backend (int type)
122{
123 if ((WithCrypto & APPLICATION_PGP) &&
124 (type & APPLICATION_PGP) &&
125 crypto_module_lookup (APPLICATION_PGP))
126 return 1;
127
128 if ((WithCrypto & APPLICATION_SMIME) &&
129 (type & APPLICATION_SMIME) &&
130 crypto_module_lookup (APPLICATION_SMIME))
131 return 1;
132
133 return 0;
134}
135
136
137
138/*
139
140 PGP
141
142*/
143
144
145/* Reset a PGP passphrase */
146void crypt_pgp_void_passphrase (void)
147{
148 if (CRYPT_MOD_CALL_CHECK (PGP, void_passphrase))
149 (CRYPT_MOD_CALL (PGP, void_passphrase)) ();
150}
151
152int crypt_pgp_valid_passphrase (void)
153{
154 if (CRYPT_MOD_CALL_CHECK (PGP, valid_passphrase))
155 return (CRYPT_MOD_CALL (PGP, valid_passphrase)) ();
156
157 return 0;
158}
159
160
161/* Decrypt a PGP/MIME message. */
162int crypt_pgp_decrypt_mime (FILE *a, FILE **b, BODY *c, BODY **d)
163{
164#ifdef USE_AUTOCRYPT
165 int result;
166
167 if (option (OPTAUTOCRYPT))
168 {
169 set_option (OPTAUTOCRYPTGPGME);
170 result = pgp_gpgme_decrypt_mime (a, b, c, d);
171 unset_option (OPTAUTOCRYPTGPGME);
172 if (result == 0)
173 {
174 c->is_autocrypt = 1;
175 return result;
176 }
177 }
178#endif
179
180 if (CRYPT_MOD_CALL_CHECK (PGP, decrypt_mime))
181 return (CRYPT_MOD_CALL (PGP, decrypt_mime)) (a, b, c, d);
182
183 return -1;
184}
185
186/* MIME handler for the application/pgp content-type. */
187int crypt_pgp_application_pgp_handler (BODY *m, STATE *s)
188{
189 if (CRYPT_MOD_CALL_CHECK (PGP, application_handler))
190 return (CRYPT_MOD_CALL (PGP, application_handler)) (m, s);
191
192 return -1;
193}
194
195/* MIME handler for an PGP/MIME encrypted message. */
196int crypt_pgp_encrypted_handler (BODY *a, STATE *s)
197{
198#ifdef USE_AUTOCRYPT
199 int result;
200
201 if (option (OPTAUTOCRYPT))
202 {
203 set_option (OPTAUTOCRYPTGPGME);
204 result = pgp_gpgme_encrypted_handler (a, s);
205 unset_option (OPTAUTOCRYPTGPGME);
206 if (result == 0)
207 {
208 a->is_autocrypt = 1;
209 return result;
210 }
211 }
212#endif
213
214 if (CRYPT_MOD_CALL_CHECK (PGP, encrypted_handler))
215 return (CRYPT_MOD_CALL (PGP, encrypted_handler)) (a, s);
216
217 return -1;
218}
219
220/* fixme: needs documentation. */
221void crypt_pgp_invoke_getkeys (ADDRESS *addr)
222{
223 if (CRYPT_MOD_CALL_CHECK (PGP, pgp_invoke_getkeys))
224 (CRYPT_MOD_CALL (PGP, pgp_invoke_getkeys)) (addr);
225}
226
227/* Check for a traditional PGP message in body B. */
228int crypt_pgp_check_traditional (FILE *fp, BODY *b, int just_one)
229{
230 if (CRYPT_MOD_CALL_CHECK (PGP, pgp_check_traditional))
231 return (CRYPT_MOD_CALL (PGP, pgp_check_traditional)) (fp, b, just_one);
232
233 return 0;
234}
235
236/* fixme: needs documentation. */
237BODY *crypt_pgp_traditional_encryptsign (BODY *a, int flags, char *keylist)
238{
239 if (CRYPT_MOD_CALL_CHECK (PGP, pgp_traditional_encryptsign))
240 return (CRYPT_MOD_CALL (PGP, pgp_traditional_encryptsign)) (a, flags, keylist);
241
242 return NULL;
243}
244
245/* Generate a PGP public key attachment. */
246BODY *crypt_pgp_make_key_attachment (void)
247{
248 if (CRYPT_MOD_CALL_CHECK (PGP, pgp_make_key_attachment))
249 return (CRYPT_MOD_CALL (PGP, pgp_make_key_attachment)) ();
250
251 return NULL;
252}
253
254/* This routine attempts to find the keyids of the recipients of a
255 message. It returns NULL if any of the keys can not be found.
256 If oppenc_mode is true, only keys that can be determined without
257 prompting will be used. */
258char *crypt_pgp_findkeys (ADDRESS *adrlist, int oppenc_mode)
259{
260 if (CRYPT_MOD_CALL_CHECK (PGP, findkeys))
261 return (CRYPT_MOD_CALL (PGP, findkeys)) (adrlist, oppenc_mode);
262
263 return NULL;
264}
265
266/* Create a new body with a PGP signed message from A. */
267BODY *crypt_pgp_sign_message (BODY *a)
268{
269 if (CRYPT_MOD_CALL_CHECK (PGP, sign_message))
270 return (CRYPT_MOD_CALL (PGP, sign_message)) (a);
271
272 return NULL;
273}
274
275/* Warning: A is no longer freed in this routine, you need to free it
276 later. This is necessary for $fcc_attach. */
277BODY *crypt_pgp_encrypt_message (HEADER *msg, BODY *a, char *keylist, int sign)
278{
279#ifdef USE_AUTOCRYPT
280 BODY *result;
281
282 if (msg->security & AUTOCRYPT)
283 {
284 if (mutt_autocrypt_set_sign_as_default_key (msg))
285 return NULL;
286
287 set_option (OPTAUTOCRYPTGPGME);
288 result = pgp_gpgme_encrypt_message (a, keylist, sign);
289 unset_option (OPTAUTOCRYPTGPGME);
290
291 return result;
292 }
293#endif
294
295 if (CRYPT_MOD_CALL_CHECK (PGP, pgp_encrypt_message))
296 return (CRYPT_MOD_CALL (PGP, pgp_encrypt_message)) (a, keylist, sign);
297
298 return NULL;
299}
300
301/* Invoke the PGP command to import a key. */
302void crypt_pgp_invoke_import (const char *fname)
303{
304 if (CRYPT_MOD_CALL_CHECK (PGP, pgp_invoke_import))
305 (CRYPT_MOD_CALL (PGP, pgp_invoke_import)) (fname);
306}
307
308/* fixme: needs documentation */
309int crypt_pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
310{
311 if (CRYPT_MOD_CALL_CHECK (PGP, verify_one))
312 return (CRYPT_MOD_CALL (PGP, verify_one)) (sigbdy, s, tempf);
313
314 return -1;
315}
316
317
318int crypt_pgp_send_menu (HEADER *msg)
319{
320 if (CRYPT_MOD_CALL_CHECK (PGP, send_menu))
321 return (CRYPT_MOD_CALL (PGP, send_menu)) (msg);
322
323 return 0;
324}
325
326
327/* fixme: needs documentation */
328void crypt_pgp_extract_keys_from_attachment_list (FILE *fp, int tag, BODY *top)
329{
330 if (CRYPT_MOD_CALL_CHECK (PGP, pgp_extract_keys_from_attachment_list))
331 (CRYPT_MOD_CALL (PGP, pgp_extract_keys_from_attachment_list)) (fp, tag, top);
332}
333
334void crypt_pgp_set_sender (const char *sender)
335{
336 if (CRYPT_MOD_CALL_CHECK (PGP, set_sender))
337 (CRYPT_MOD_CALL (PGP, set_sender)) (sender);
338}
339
340
341
342
343/*
344
345 S/MIME
346
347*/
348
349
350/* Reset an SMIME passphrase */
351void crypt_smime_void_passphrase (void)
352{
353 if (CRYPT_MOD_CALL_CHECK (SMIME, void_passphrase))
354 (CRYPT_MOD_CALL (SMIME, void_passphrase)) ();
355}
356
357int crypt_smime_valid_passphrase (void)
358{
359 if (CRYPT_MOD_CALL_CHECK (SMIME, valid_passphrase))
360 return (CRYPT_MOD_CALL (SMIME, valid_passphrase)) ();
361
362 return 0;
363}
364
365/* Decrypt am S/MIME message. */
366int crypt_smime_decrypt_mime (FILE *a, FILE **b, BODY *c, BODY **d)
367{
368 if (CRYPT_MOD_CALL_CHECK (SMIME, decrypt_mime))
369 return (CRYPT_MOD_CALL (SMIME, decrypt_mime)) (a, b, c, d);
370
371 return -1;
372}
373
374/* MIME handler for the application/smime content-type. */
375int crypt_smime_application_smime_handler (BODY *m, STATE *s)
376{
377 if (CRYPT_MOD_CALL_CHECK (SMIME, application_handler))
378 return (CRYPT_MOD_CALL (SMIME, application_handler)) (m, s);
379
380 return -1;
381}
382
383/* MIME handler for an PGP/MIME encrypted message. */
384void crypt_smime_encrypted_handler (BODY *a, STATE *s)
385{
386 if (CRYPT_MOD_CALL_CHECK (SMIME, encrypted_handler))
387 (CRYPT_MOD_CALL (SMIME, encrypted_handler)) (a, s);
388}
389
390/* fixme: Needs documentation. */
391void crypt_smime_getkeys (ENVELOPE *env)
392{
393 if (CRYPT_MOD_CALL_CHECK (SMIME, smime_getkeys))
394 (CRYPT_MOD_CALL (SMIME, smime_getkeys)) (env);
395}
396
397/* Check that the sender matches. */
398int crypt_smime_verify_sender(HEADER *h)
399{
400 if (CRYPT_MOD_CALL_CHECK (SMIME, smime_verify_sender))
401 return (CRYPT_MOD_CALL (SMIME, smime_verify_sender)) (h);
402
403 return 1;
404}
405
406/* This routine attempts to find the keyids of the recipients of a
407 message. It returns NULL if any of the keys can not be found.
408 If oppenc_mode is true, only keys that can be determined without
409 prompting will be used. */
410char *crypt_smime_findkeys (ADDRESS *adrlist, int oppenc_mode)
411{
412 if (CRYPT_MOD_CALL_CHECK (SMIME, findkeys))
413 return (CRYPT_MOD_CALL (SMIME, findkeys)) (adrlist, oppenc_mode);
414
415 return NULL;
416}
417
418/* fixme: Needs documentation. */
419BODY *crypt_smime_sign_message (BODY *a)
420{
421 if (CRYPT_MOD_CALL_CHECK (SMIME, sign_message))
422 return (CRYPT_MOD_CALL (SMIME, sign_message)) (a);
423
424 return NULL;
425}
426
427/* fixme: needs documentation. */
428BODY *crypt_smime_build_smime_entity (BODY *a, char *certlist)
429{
430 if (CRYPT_MOD_CALL_CHECK (SMIME, smime_build_smime_entity))
431 return (CRYPT_MOD_CALL (SMIME, smime_build_smime_entity)) (a, certlist);
432
433 return NULL;
434}
435
436/* Add a certificate and update index file (externally). */
437void crypt_smime_invoke_import (const char *infile, const char *mailbox)
438{
439 if (CRYPT_MOD_CALL_CHECK (SMIME, smime_invoke_import))
440 (CRYPT_MOD_CALL (SMIME, smime_invoke_import)) (infile, mailbox);
441}
442
443/* fixme: needs documentation */
444int crypt_smime_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
445{
446 if (CRYPT_MOD_CALL_CHECK (SMIME, verify_one))
447 return (CRYPT_MOD_CALL (SMIME, verify_one)) (sigbdy, s, tempf);
448
449 return -1;
450}
451
452int crypt_smime_send_menu (HEADER *msg)
453{
454 if (CRYPT_MOD_CALL_CHECK (SMIME, send_menu))
455 return (CRYPT_MOD_CALL (SMIME, send_menu)) (msg);
456
457 return 0;
458}
459
460void crypt_smime_set_sender (const char *sender)
461{
462 if (CRYPT_MOD_CALL_CHECK (SMIME, set_sender))
463 (CRYPT_MOD_CALL (SMIME, set_sender)) (sender);
464}