From 1c309b14c41ba3305bc72404fa290769251fda4a Mon Sep 17 00:00:00 2001 From: Not Zed Date: Fri, 31 May 2002 01:05:47 +0000 Subject: Added a protocol field for users to use. 2002-05-30 Not Zed * camel-cipher-context.h: Added a protocol field for users to use. * camel-stream-filter.c (do_read): Sigh, the pre-size is READ_PAD not READ_SIZE. Big difference. (READ_PAD): Bumped upto 128 from 64, so we can fit a typical line in full. * providers/imap/camel-imap-folder.c (get_content): Changed to load multipart/signed as an opaque block into the right kind of object. * camel-multipart.h (struct _CamelMultipart): Removed the boundary field. It wans't actually used anywhere. * camel-seekable-substream.c (camel_seekable_substream_new_with_seekable_stream_and_bounds): Shortened this stupidly long name to just :new(), its the only way its ever used. Fixed all callers. * camel-multipart-signed.[ch]: new wrapper for multipart/signed types. We need to treat the entire content as a blob of data for transport purposes. This also cleans up a lot of the sign/verify handling. * camel-mime-part-utils.c (camel_mime_part_construct_content_from_parser): Just call camel_multipart_construct_from_parser for multipart parts, also use a multipart_signed for multipart/signed types. * camel-multipart.c (camel_multipart_construct_from_parser): New virtual function for multiparts to buld themselves. (construct_from_parser): Implement for normal multiparts. (toplevel): Got rid of a warning, it'll never be an abstract class. * camel-pgp-context.c (pgp_hash_to_id): (pgp_id_to_hash): Implement. (camel_pgp_context_init): Init the pgp protocol specifier. * camel-cipher-context.c (camel_cipher_id_to_hash): (camel_cipher_hash_to_id): Util virtual methods to handle the cipher id string. * camel-mime-filter-canon.[ch]: A new filter, end/start of line canonicalisation filter. Can escape "From " and strip trailing whitespace, and canonicalise the end of line to crlf or to lf. 2002-05-29 Not Zed * camel-multipart.h (struct _CamelMultipart): Removed the 'parent', nothing used it, anywhere. Cleaned up some formatting slightly. svn path=/trunk/; revision=17057 --- camel/camel-mime-filter-canon.c | 226 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 camel/camel-mime-filter-canon.c (limited to 'camel/camel-mime-filter-canon.c') diff --git a/camel/camel-mime-filter-canon.c b/camel/camel-mime-filter-canon.c new file mode 100644 index 0000000000..0fd48fb7b3 --- /dev/null +++ b/camel/camel-mime-filter-canon.c @@ -0,0 +1,226 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2002 Ximian, Inc. + * + * Authors: Jeffrey Stedfast + * Michael Zucchi + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* canonicalisation filter, used for secure mime incoming and outgoing */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "camel-mime-filter-canon.h" + +static void filter (CamelMimeFilter *f, char *in, size_t len, size_t prespace, + char **out, size_t *outlen, size_t *outprespace); +static void complete (CamelMimeFilter *f, char *in, size_t len, + size_t prespace, char **out, size_t *outlen, + size_t *outprespace); +static void reset (CamelMimeFilter *f); + + +static void +camel_mime_filter_canon_class_init (CamelMimeFilterCanonClass *klass) +{ + CamelMimeFilterClass *mime_filter_class = (CamelMimeFilterClass *) klass; + + mime_filter_class->filter = filter; + mime_filter_class->complete = complete; + mime_filter_class->reset = reset; +} + +CamelType +camel_mime_filter_canon_get_type (void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + type = camel_type_register (camel_mime_filter_get_type(), "CamelMimeFilterCanon", + sizeof (CamelMimeFilterCanon), + sizeof (CamelMimeFilterCanonClass), + (CamelObjectClassInitFunc) camel_mime_filter_canon_class_init, + NULL, + NULL, + NULL); + } + + return type; +} + +static void +filter(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace) +{ + register unsigned char *inptr, c; + const unsigned char *inend, *start; + char *starto; + register char *o; + int lf = 0; + guint32 flags; + + flags = ((CamelMimeFilterCanon *)f)->flags; + + /* first, work out how much space we need */ + inptr = in; + inend = in+len; + while (inptr < inend) + if (*inptr++ == '\n') + lf++; + + /* worst case, extra 3 chars per line + "From \n" -> "=46rom \r\n" + We add 1 extra incase we're called from complete, when we didn't end in \n */ + + camel_mime_filter_set_size(f, len+lf*3+4, FALSE); + + o = f->outbuf; + inptr = in; + start = inptr; + starto = o; + while (inptr < inend) { + /* first, check start of line, we always start at the start of the line */ + c = *inptr; + if (flags & CAMEL_MIME_FILTER_CANON_FROM && c == 'F') { + inptr++; + if (inptr < inend-4) { + if (strncmp(inptr, "rom ", 4) == 0) { + *o++ = '='; + *o++ = '4'; + *o++ = '6'; + } else + *o++ = 'F'; + *o++ = *inptr++; + *o++ = *inptr++; + *o++ = *inptr++; + *o++ = *inptr++; + } else { + break; + } + } + + /* now scan for end of line */ + while (inptr < inend) { + c = *inptr++; + if (c == '\n') { + /* check to strip trailing space */ + if (flags & CAMEL_MIME_FILTER_CANON_STRIP) { + while (o>starto && (o[-1] == ' ' || o[-1] == '\t' || o[-1]=='\r')) + o--; + } + /* check end of line canonicalisation */ + if (o>starto) { + if (flags & CAMEL_MIME_FILTER_CANON_CRLF) { + if (o[-1] != '\r') + *o++ = '\r'; + } else { + if (o[-1] == '\r') + o--; + } + } + *o++ = c; + start = inptr; + starto = o; + break; + } else + *o++ = c; + } + } + + /* TODO: We should probably track if we end somewhere in the middle of a line, + otherwise we potentially backup a full line, which could be large */ + + /* we got to the end of the data without finding anything, backup to start and re-process next time around */ + camel_mime_filter_backup(f, start, inend - start); + + *out = f->outbuf; + *outlen = starto - f->outbuf; + *outprespace = f->outpre; +} + +static void +complete(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace) +{ + unsigned char *inptr, *inend; + char *o, *starto; + guint32 flags; + + if (len) + filter(f, in, len, prespace, out, outlen, outprespace); + + /* the data didn't contain an eol or was too short for "From ", we only need to check for "From" and add an eol */ + if (f->backlen) { + inptr = (unsigned char *)f->backbuf; + inend = (unsigned char *)f->backbuf + f->backlen; + starto = o = *out + *outlen; + flags = ((CamelMimeFilterCanon *)f)->flags; + + /* Check any embedded "From " */ + if (f->backlen >= 5 + && (flags & CAMEL_MIME_FILTER_CANON_FROM) + && strcmp(inptr, "From ") == 0) { + strcpy(o, "=46rom "); + o += 7; + inptr += 5; + } + + /* copy the rest of it */ + while (inptr < inend) + *o++ = *inptr++; + + /* check to strip trailing space */ + if (flags & CAMEL_MIME_FILTER_CANON_STRIP) { + while (o>starto && (o[-1] == ' ' || o[-1] == '\t' || o[-1]=='\r')) + o--; + } + /* check end of line canonicalisation */ + if (o>starto) { + if (flags & CAMEL_MIME_FILTER_CANON_CRLF) { + if (o[-1] != '\r') + *o++ = '\r'; + } else { + if (o[-1] == '\r') + o--; + } + } + + /* and always finish with an eol */ + *o++ = '\n'; + + *outlen = o - *out; + } +} + +static void +reset (CamelMimeFilter *f) +{ + /* no-op */ +} + +CamelMimeFilter * +camel_mime_filter_canon_new(guint32 flags) +{ + CamelMimeFilterCanon *chomp = CAMEL_MIME_FILTER_CANON (camel_object_new (CAMEL_MIME_FILTER_CANON_TYPE)); + + chomp->flags = flags; + + return (CamelMimeFilter *) chomp; +} -- cgit v1.2.3