1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2005 Matt Brown.
5 * Authors: Matt Brown <matt@mattb.net.nz>
6 * Jeffrey Stedfast <fejj@novell.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU Lesser General Public
10 * License as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
23 /* Strips PGP message headers from the input stream and also performs
24 * pgp decoding as described in section 7.1 of RFC2440 */
33 #include "camel-mime-filter-pgp.h"
35 static void filter (CamelMimeFilter *f, char *in, size_t len, size_t prespace,
36 char **out, size_t *outlen, size_t *outprespace);
37 static void complete (CamelMimeFilter *f, char *in, size_t len,
38 size_t prespace, char **out, size_t *outlen,
40 static void reset (CamelMimeFilter *f);
50 camel_mime_filter_pgp_class_init (CamelMimeFilterPgpClass *klass)
52 CamelMimeFilterClass *mime_filter_class = (CamelMimeFilterClass *) klass;
54 mime_filter_class->filter = filter;
55 mime_filter_class->complete = complete;
56 mime_filter_class->reset = reset;
60 camel_mime_filter_pgp_get_type (void)
62 static CamelType type = CAMEL_INVALID_TYPE;
64 if (type == CAMEL_INVALID_TYPE) {
65 type = camel_type_register (camel_mime_filter_get_type (),
67 sizeof (CamelMimeFilterPgp),
68 sizeof (CamelMimeFilterPgpClass),
69 (CamelObjectClassInitFunc) camel_mime_filter_pgp_class_init,
78 #define BEGIN_PGP_SIGNED_MESSAGE "-----BEGIN PGP SIGNED MESSAGE-----"
79 #define BEGIN_PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
80 #define END_PGP_SIGNATURE "-----END PGP SIGNATURE-----"
83 filter_run(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace, int last)
85 CamelMimeFilterPgp *pgp = (CamelMimeFilterPgp *) f;
86 const char *start, *inend = in + len;
87 register const char *inptr = in;
90 /* only need as much space as the input, we're stripping chars */
91 camel_mime_filter_set_size (f, len, FALSE);
95 while (inptr < inend) {
98 while (inptr < inend && *inptr != '\n')
101 if (inptr == inend) {
103 camel_mime_filter_backup (f, start, inend - start);
111 switch (pgp->state) {
113 /* check for the beginning of the pgp block */
114 if (!strncmp (start, BEGIN_PGP_SIGNED_MESSAGE, sizeof (BEGIN_PGP_SIGNED_MESSAGE) - 1)) {
119 memcpy (o, start, inptr - start);
120 o += (inptr - start);
123 /* pgp headers (Hash: SHA1, etc) end with a blank (zero-length,
124 or containing only whitespace) line; see RFC2440 */
125 if ((inptr - start) == 1 || ((inptr - start) == 2 && *(inptr - 2) == 0x20))
129 /* check for beginning of the pgp signature block */
130 if (!strncmp (start, BEGIN_PGP_SIGNATURE, sizeof (BEGIN_PGP_SIGNATURE) - 1)) {
135 /* do dash decoding */
136 if (!strncmp (start, "- ", 2)) {
137 /* Dash encoded line found, skip encoding */
141 memcpy (o, start, inptr - start);
142 o += (inptr - start);
145 if (!strncmp (start, END_PGP_SIGNATURE, sizeof (END_PGP_SIGNATURE) - 1))
146 pgp->state = PGP_PREFACE;
152 *outlen = o - f->outbuf;
153 *outprespace = f->outpre;
157 filter (CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace)
159 filter_run (f, in, len, prespace, out, outlen, outprespace, FALSE);
163 complete (CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace)
165 filter_run (f, in, len, prespace, out, outlen, outprespace, TRUE);
169 reset (CamelMimeFilter *f)
171 ((CamelMimeFilterPgp *) f)->state = PGP_PREFACE;
175 camel_mime_filter_pgp_new(void)
177 return (CamelMimeFilter *) camel_object_new (camel_mime_filter_pgp_get_type ());