[evolution-patches] small patch for security




As the comment says, this doesn't really make a huge security difference, but provides a first-level attempt, and the start of an api for it.

It Just munges memory of decrypted parts after we're finished with them, rather than leaving the data around in memory for bugs to potentially expose the data.  Of course this doesn't affect any mimefilters or gtkhtml data either ...

(i left the other outstanding camel bug in the diff 'cause i'm lazy)

--
Michael Zucchi <notzed ximian com>

Novell's Evolution and Free Software Developer
Index: camel/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/camel/ChangeLog,v
retrieving revision 1.2213
diff -u -3 -r1.2213 ChangeLog
--- camel/ChangeLog	2 Jul 2004 12:19:34 -0000	1.2213
+++ camel/ChangeLog	9 Jul 2004 05:10:43 -0000
@@ -1,3 +1,29 @@
+2004-07-09  Not Zed  <NotZed Ximian com>
+
+	** This is no guarantee of security, but its just a helper to
+	prevent old memory accidentally being included/used elsewhere.
+	
+	* camel-smime-context.c (sm_decrypt): mark the output stream
+	'secure'.
+
+	* camel-gpg-context.c (gpg_decrypt): set the output stream to
+	secured, so we automagically blank it out on finalise.
+
+	* camel-stream-mem.c (camel_stream_mem_set_secure): set the
+	memory-stream 'secured', all we do at the moment is blank out the
+	buffer on finalise.
+	(camel_stream_mem_set_byte_array, camel_stream_mem_finalize):
+	clear memory if owner and secured.  kill dead comment.
+	(clear_mem): utilitiy to set memory to 0xABADF00D
+
+2004-07-08  Not Zed  <NotZed Ximian com>
+
+	** See bug #61186.
+	
+	* camel-cipher-context.c (camel_cipher_sign):
+	(camel_cipher_verify, camel_cipher_encrypt, camel_cipher_decrypt):
+	Add preliminary progress reporting.
+
 2004-07-02  Christian Neumair  <chris gnome-de org>
 
 	* camel-smime-context.c: s/Can't/Cannot/.
Index: camel/camel-cipher-context.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-cipher-context.c,v
retrieving revision 1.17
diff -u -3 -r1.17 camel-cipher-context.c
--- camel/camel-cipher-context.c	10 Dec 2003 05:25:24 -0000	1.17
+++ camel/camel-cipher-context.c	9 Jul 2004 05:10:43 -0000
@@ -31,6 +31,7 @@
 
 #include "camel-cipher-context.h"
 #include "camel-stream.h"
+#include "camel-operation.h"
 
 #include "camel-mime-utils.h"
 #include "camel-medium.h"
@@ -123,13 +124,17 @@
 	int retval;
 	
 	g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1);
-	
+
+	camel_operation_start_transient(NULL, _("Signing message"));
+
 	CIPHER_LOCK(context);
 	
 	retval = CCC_CLASS (context)->sign (context, userid, hash, ipart, opart, ex);
 	
 	CIPHER_UNLOCK(context);
-	
+
+	camel_operation_end(NULL);
+
 	return retval;
 }
 
@@ -163,11 +168,15 @@
 	
 	g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL);
 	
+	camel_operation_start_transient(NULL, _("Verifying message"));
+
 	CIPHER_LOCK(context);
 	
 	valid = CCC_CLASS (context)->verify (context, ipart, ex);
 	
 	CIPHER_UNLOCK(context);
+
+	camel_operation_end(NULL);
 	
 	return valid;
 }
@@ -202,12 +211,16 @@
 	int retval;
 	
 	g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), -1);
+
+	camel_operation_start_transient(NULL, _("Encrypting message"));
 	
 	CIPHER_LOCK(context);
 	
 	retval = CCC_CLASS (context)->encrypt (context, userid, recipients, ipart, opart, ex);
 	
 	CIPHER_UNLOCK(context);
+
+	camel_operation_end(NULL);
 	
 	return retval;
 }
@@ -237,12 +250,16 @@
 	CamelCipherValidity *valid;
 
 	g_return_val_if_fail (CAMEL_IS_CIPHER_CONTEXT (context), NULL);
+
+	camel_operation_start_transient(NULL, _("Decrypting message"));
 	
 	CIPHER_LOCK(context);
 	
 	valid = CCC_CLASS (context)->decrypt (context, ipart, opart, ex);
 	
 	CIPHER_UNLOCK(context);
+
+	camel_operation_end(NULL);
 	
 	return valid;
 }
Index: camel/camel-gpg-context.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-gpg-context.c,v
retrieving revision 1.60
diff -u -3 -r1.60 camel-gpg-context.c
--- camel/camel-gpg-context.c	15 Jun 2004 15:19:23 -0000	1.60
+++ camel/camel-gpg-context.c	9 Jul 2004 05:10:43 -0000
@@ -1621,6 +1621,7 @@
 	camel_stream_filter_add (CAMEL_STREAM_FILTER (filtered_stream), crlf_filter);
 	camel_object_unref (crlf_filter);*/
 	ostream = camel_stream_mem_new();
+	camel_stream_mem_set_secure((CamelStreamMem *)ostream);
 
 	gpg = gpg_ctx_new (context->session);
 	gpg_ctx_set_mode (gpg, GPG_CTX_MODE_DECRYPT);
Index: camel/camel-smime-context.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-smime-context.c,v
retrieving revision 1.36
diff -u -3 -r1.36 camel-smime-context.c
--- camel/camel-smime-context.c	2 Jul 2004 12:19:34 -0000	1.36
+++ camel/camel-smime-context.c	9 Jul 2004 05:10:43 -0000
@@ -953,6 +953,7 @@
 	   this api to do this ... */
 
 	ostream = camel_stream_mem_new();
+	camel_stream_mem_set_secure((CamelStreamMem *)ostream);
 
 	/* FIXME: stream this to the decoder incrementally */
 	istream = (CamelStreamMem *)camel_stream_mem_new();
Index: camel/camel-stream-mem.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-stream-mem.c,v
retrieving revision 1.32
diff -u -3 -r1.32 camel-stream-mem.c
--- camel/camel-stream-mem.c	28 Mar 2003 00:13:43 -0000	1.32
+++ camel/camel-stream-mem.c	9 Jul 2004 05:10:43 -0000
@@ -74,6 +74,23 @@
 	stream_mem->buffer = 0;
 }
 
+/* could probably be a util method */
+static void clear_mem(void *p, size_t len)
+{
+	char *s = p;
+
+	/* This also helps debug bad access memory errors */
+	while (len > 4) {
+		*s++ = 0xAB;
+		*s++ = 0xAD;
+		*s++ = 0xF0;
+		*s++ = 0x0D;
+		len -= 4;
+	}
+
+	memset(s, 0xbf, len);
+}
+
 CamelType
 camel_stream_mem_get_type (void)
 {
@@ -122,11 +139,28 @@
 	return CAMEL_STREAM (stream_mem);
 }
 
+/**
+ * camel_stream_mem_set_secure:
+ * @s: 
+ * 
+ * Mark the memory stream as secure.  At the very least this means the
+ * data in the buffer will be cleared when the buffer is finalised.
+ * This only applies to buffers owned by the stream.
+ **/
+void camel_stream_mem_set_secure(CamelStreamMem *s)
+{
+	s->secure = 1;
+	/* setup a mem-locked buffer etc?  blah blah, well not yet anyway */
+}
+
 /* note: with these functions the caller is the 'owner' of the buffer */
 void camel_stream_mem_set_byte_array (CamelStreamMem *s, GByteArray *buffer)
 {
-	if (s->buffer && s->owner)
+	if (s->buffer && s->owner) {
+		if (s->secure && s->buffer->len)
+			clear_mem(s->buffer->data, s->buffer->len);
 		g_byte_array_free(s->buffer, TRUE);
+	}
 	s->owner = FALSE;
 	s->buffer = buffer;
 }
@@ -144,15 +178,15 @@
 static void
 camel_stream_mem_finalize (CamelObject *object)
 {
-	CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (object);
+	CamelStreamMem *s = CAMEL_STREAM_MEM (object);
 
-	if (stream_mem->buffer && stream_mem->owner)
-		g_byte_array_free (stream_mem->buffer, TRUE);
-
-	/* Will be called automagically in the Camel Type System!
-	 * Wheeee!
-	 * G_TK_OBJECT_CLASS (parent_class)->finalize (object);
-	 */
+	if (s->buffer && s->owner) {
+		/* TODO: we need our own bytearray type since we don't know
+		   the real size of the underlying buffer :-/ */
+		if (s->secure && s->buffer->len)
+			clear_mem(s->buffer->data, s->buffer->len);
+		g_byte_array_free(s->buffer, TRUE);
+	}
 }
 
 static ssize_t
Index: camel/camel-stream-mem.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-stream-mem.h,v
retrieving revision 1.23
diff -u -3 -r1.23 camel-stream-mem.h
--- camel/camel-stream-mem.h	27 Oct 2001 16:59:27 -0000	1.23
+++ camel/camel-stream-mem.h	9 Jul 2004 05:10:43 -0000
@@ -45,7 +45,8 @@
 struct _CamelStreamMem {
 	CamelSeekableStream parent_object;
 
-	gboolean owner;		/* do we own the buffer? */
+	unsigned int owner:1;	/* do we own the buffer? */
+	unsigned int secure:1;	/* do we clear the buffer on finalise (if we own it) */
 	GByteArray *buffer;
 };
 
@@ -62,6 +63,9 @@
 CamelStream *camel_stream_mem_new(void);
 CamelStream *camel_stream_mem_new_with_byte_array(GByteArray *buffer);
 CamelStream *camel_stream_mem_new_with_buffer(const char *buffer, size_t len);
+
+/* 'secure' data, currently just clears memory on finalise */
+void camel_stream_mem_set_secure(CamelStreamMem *);
 
 /* these are really only here for implementing classes */
 void camel_stream_mem_set_byte_array(CamelStreamMem *, GByteArray *buffer);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]