The NNTP patch is a joke, let's drop it altogether.
[apps/madmutt.git] / lib-mime / crypt.c
1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or (at
5  *  your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful, but
8  *  WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  *  General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15  *  MA 02110-1301, USA.
16  *
17  *  Copyright © 2006 Pierre Habouzit
18  */
19 /*
20  * Copyright notice from original mutt:
21  * Copyright (C) 1996,1997 Michael R. Elkins <me@mutt.org>
22  * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org>
23  * Copyright (C) 2001  Thomas Roessler <roessler@does-not-exist.org>
24  *                     Oliver Ehli <elmy@acm.org>
25  * Copyright (C) 2003  Werner Koch <wk@gnupg.org>
26  * Copyright (C) 2004 g10code GmbH
27  *
28  * This file is part of mutt-ng, see http://www.muttng.org/.
29  * It's licensed under the GNU General Public License,
30  * please see the file GPL in the top level source directory.
31  */
32
33 #include <lib-lib/lib-lib.h>
34
35 #include "mime.h"
36 #include "crypt.h"
37
38 int mutt_is_multipart_signed(BODY * b)
39 {
40     char *p;
41
42     if (!b || b->type != TYPEMULTIPART || !b->subtype
43         ||  mime_which_token(b->subtype, -1) != MIME_SIGNED)
44         return 0;
45
46     if (!(p = parameter_getval(b->parameter, "protocol")))
47         return 0;
48
49     switch (mime_which_token(p, -1)) {
50       case MIME_MULTIPART_MIXED:
51         return SIGN;
52
53       case MIME_APPLICATION_PGP_SIGNATURE:
54         return PGPSIGN;
55
56       case MIME_APPLICATION_X_PKCS7_SIGNATURE:
57         return SMIMESIGN;
58
59       case MIME_APPLICATION_PKCS7_SIGNATURE:
60         return SMIMESIGN;
61
62       default:
63         return 0;
64     }
65 }
66
67 int mutt_is_multipart_encrypted (BODY * b)
68 {
69     char *p;
70
71     if (!b || b->type != TYPEMULTIPART || !b->subtype
72     ||  mime_which_token(b->subtype, -1) != MIME_ENCRYPTED
73     ||  !(p = parameter_getval(b->parameter, "protocol"))
74     ||  mime_which_token(p, -1) != MIME_APPLICATION_PGP_ENCRYPTED)
75         return 0;
76
77     return PGPENCRYPT;
78 }
79
80 int mutt_is_application_pgp (BODY * m)
81 {
82     int t = 0;
83
84     int subtype = mime_which_token(m->subtype, -1);
85
86     if (m->type == TYPEAPPLICATION) {
87         if (subtype == MIME_PGP || subtype == MIME_X_PGP_MESSAGE) {
88             int tok;
89
90             tok = mime_which_token(parameter_getval(m->parameter, "x-action"), -1);
91             if (tok == MIME_SIGN || tok == MIME_SIGNCLEAR)
92                 t |= PGPSIGN;
93
94             tok = mime_which_token(parameter_getval(m->parameter, "format"), -1);
95             if (tok == MIME_KEYS_ONLY)
96                 t |= PGPKEY;
97
98             if (!t)
99                 t |= PGPENCRYPT;        /* not necessarily correct, but... */
100         }
101
102         if (subtype == MIME_PGP_SIGNED)
103             t |= PGPSIGN;
104
105         if (subtype == MIME_PGP_KEYS)
106             t |= PGPKEY;
107     }
108
109     if (m->type == TYPETEXT && subtype == MIME_PLAIN) {
110         const char *p;
111
112         if ((p = parameter_getval(m->parameter, "x-action"))) {
113             int tok = mime_which_token(p, -1);
114             switch (tok) {
115               case MIME_PGP_SIGNED:
116                 t |= PGPSIGN;
117                 break;
118
119               case MIME_PGP_ENCRYPTED:
120                 t |= PGPENCRYPT;
121                 break;
122
123               case MIME_PGP_KEYS:
124                 t |= PGPKEY;
125                 break;
126
127               default:
128                 break;
129             }
130         }
131     }
132
133     return t ? t | PGPINLINE : 0;
134 }
135
136 #include "mutt.h"
137
138 int mutt_is_application_smime (BODY * m)
139 {
140     char *t = NULL;
141     int len, complain = 0;
142
143     if (!m)
144         return 0;
145
146     if ((m->type & TYPEAPPLICATION) && m->subtype) {
147         int subtype = mime_which_token(m->subtype, -1);
148
149         /* S/MIME MIME types don't need x- anymore, see RFC2311 */
150         if (subtype == MIME_X_PKCS7_MIME || subtype == MIME_PKCS7_MIME) {
151             t = parameter_getval(m->parameter, "smime-type");
152
153             if (t) {
154                 switch (mime_which_token(t, -1)) {
155                   case MIME_ENVELOPED_DATA:
156                     return SMIMEENCRYPT;
157
158                   case MIME_SIGNED_DATA:
159                     return SMIMESIGN | SMIMEOPAQUE;
160
161                   default:
162                     return 0;
163                 }
164             }
165
166             complain = 1;
167         }
168
169         if (subtype == MIME_OCTET_STREAM)
170             return 0;
171
172         t = parameter_getval(m->parameter, "name");
173         if (!t)
174             t = m->d_filename;
175         if (!t)
176             t = m->filename;
177
178         if (!t) {
179             if (complain)
180                 mutt_message(_("S/MIME messages with no hints on content are unsupported."));
181             return 0;
182         }
183
184         /* no .p7c, .p10 support yet. */
185
186         len = m_strlen(t) - 4;
187         if (len > 0 && t[len] == '.'
188         &&  tolower((unsigned char)t[len + 1]) == 'p'
189         &&  t[len + 2] == '7')
190         {
191             switch (t[len + 3]) {
192               case 'm': case 'M':
193                 /* Not sure if this is the correct thing to do, but 
194                    it's required for compatibility with Outlook */
195                 return (SMIMESIGN | SMIMEOPAQUE);
196
197               case 's': case 'S':
198                 return (SMIMESIGN | SMIMEOPAQUE);
199             }
200         }
201     }
202
203     return 0;
204 }
205
206