Sophie

Sophie

distrib > Fedora > 13 > i386 > by-pkgid > cb363eebcf2756c4cb16e526efc09d35 > files > 3

dbmail-2.2.17-1.fc13.src.rpm

From b85ccaadf2ddb41b29c1664c4be5e4b6aa31d212 Mon Sep 17 00:00:00 2001
From: Paul J Stevens <paul@nfg.nl>
Date: Tue, 10 Nov 2009 12:10:36 +0000
Subject: change md5 implementation (bug #816)

Use GLib's md5 implementation. This introduces a dependency on glib >= 2.16
which is enforced by configure.
---
diff --git a/INSTALL b/INSTALL
index ccd6137..07edd52 100644
--- a/INSTALL
+++ b/INSTALL
@@ -18,7 +18,7 @@ What do you need?
   systems, make sure you install and use 'gmake'. 
 - Development files (libs, scripts and include files) for your database server.
   These will probably be provided by separate packages.
-- Glib (>= 2.8) development headers and libraries.
+- Glib (>= 2.16) development headers and libraries.
 - Gmime (>= 2.1.18) development headers and libraries.
 - libSieve for Sieve support (libsieve.sf.net).
 - Any standard libldap for LDAP support (only tested with OpenLDAP, however).
diff --git a/Makefile.am b/Makefile.am
index 2d931d4..0f90d09 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -128,6 +128,7 @@ TESTS=check_dbmail_common \
 	check_dbmail_mailbox \
 	check_dbmail_auth \
 	check_dbmail_misc \
+	check_dbmail_md5 \
 	check_dbmail_list \
 	check_dbmail_user \
 	check_dbmail_util \
@@ -149,6 +150,10 @@ check_dbmail_misc_SOURCES=check_dbmail_misc.c
 check_dbmail_misc_LDADD=libdbmail.la @CHECK_LIBS@
 check_dbmail_misc_INCLUDES=@CHECK_CFLAGS@
 
+check_dbmail_md5_SOURCES=check_dbmail_md5.c
+check_dbmail_md5_LDADD=libdbmail.la @CHECK_LIBS@
+check_dbmail_md5_INCLUDES=@CHECK_CFLAGS@
+
 check_dbmail_list_SOURCES=check_dbmail_list.c
 check_dbmail_list_LDADD=libdbmail.la @CHECK_LIBS@
 check_dbmail_list_INCLUDES=@CHECK_CFLAGS@
diff --git a/acinclude.m4 b/acinclude.m4
index 898938a..e366d9d 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -501,6 +501,15 @@ dnl First we're looking for straight GLib
 		AC_MSG_ERROR([Unable to locate glib libaries])
 	fi
  
+        ac_glib_minvers="2.16"
+        AC_MSG_CHECKING([GLib version >= $ac_glib_minvers])
+        ac_glib_vers=`${glibconfig}  --atleast-version=$ac_glib_minvers glib-2.0 && echo yes`
+        if test -z "$ac_glib_vers"
+        then
+                AC_MSG_ERROR([At least GLib version $ac_glib_minvers is required.])
+        else
+                AC_MSG_RESULT([$ac_glib_vers])
+        fi
 
 	LDFLAGS="$LDFLAGS $ac_glib_libs"
         AC_MSG_RESULT([$ac_glib_libs])
diff --git a/check_dbmail_md5.c b/check_dbmail_md5.c
new file mode 100644
index 0000000..4b4863a
--- a/dev/null
+++ b/check_dbmail_md5.c
@@ -0,0 +1,97 @@
+/*
+ *   Copyright (c) 2005-2006 NFG Net Facilities Group BV support@nfg.nl
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either
+ *   version 2 of the License, or (at your option) any later
+ *   version.
+ *
+ *   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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ *   
+ *
+ *
+ *  
+ *
+ *   Basic unit-test framework for dbmail (www.dbmail.org)
+ *
+ *   See http://check.sf.net for details and docs.
+ *
+ *
+ *   Run 'make check' to see some action.
+ *
+ */ 
+
+#include <check.h>
+#include "check_dbmail.h"
+
+extern char *configFile;
+
+/*
+ *
+ * the test fixtures
+ *
+ */
+void setup(void)
+{
+	configure_debug(5,0);
+}
+
+void teardown(void)
+{
+	;
+}
+
+#define M(a,b) fail_unless(MATCH(dm_md5((a)),(b)), "dm_md5 failed [%s] != [%s]", dm_md5(a), b)
+START_TEST(test_md5)
+{
+        M("","d41d8cd98f00b204e9800998ecf8427e");
+        M("a","0cc175b9c0f1b6a831c399e269772661");
+        M("abc", "900150983cd24fb0d6963f7d28e17f72");
+}
+END_TEST
+
+#define B(a,b) fail_unless(MATCH(dm_md5_base64((a)),(b)), "dm_md5_base64 failed [%s] != [%s]", dm_md5(a), b)
+START_TEST(test_md5_base64)
+{
+	B("","1B2M2Y8AsgTpgAmY7PhCfg==");
+	B("a","DMF1ucDxtqgxw5niaXcmYQ==");
+	B("abc","kAFQmDzST7DWlj99KOF/cg==");
+}
+END_TEST
+
+Suite *dbmail_common_suite(void)
+{
+	Suite *s = suite_create("Dbmail md5");
+	TCase *tc_util = tcase_create("Md5");
+	
+	suite_add_tcase(s, tc_util);
+	
+	tcase_add_checked_fixture(tc_util, setup, teardown);
+	tcase_add_test(tc_util, test_md5);
+	tcase_add_test(tc_util, test_md5_base64);
+
+	return s;
+}
+
+int main(void)
+{
+	int nf;
+	Suite *s = dbmail_common_suite();
+	SRunner *sr = srunner_create(s);
+	srunner_run_all(sr, CK_NORMAL);
+	nf = srunner_ntests_failed(sr);
+	srunner_free(sr);
+	return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+	
+
diff --git a/dm_md5.c b/dm_md5.c
index 3fdebcf..09a064f 100644
--- a/dm_md5.c
+++ b/dm_md5.c
@@ -43,280 +43,20 @@
 #include "dbmail.h"
 #define THIS_MODULE "md5"
 
-typedef unsigned int uint32;
-
-struct GdmMD5Context {
-	uint32 buf[4];
-	uint32 bits[2];
-	unsigned char in[64];
-};
-
-static void gdm_md5_init(struct GdmMD5Context *context);
-static void gdm_md5_update(struct GdmMD5Context *context,
-		    unsigned char const *buf, unsigned len);
-static void gdm_md5_final(unsigned char digest[16],
-		   struct GdmMD5Context *context);
-static void gdm_md5_transform(uint32 buf[4], uint32 const in[16]);
-
-
-/* If endian.h is present, it will tell us, otherwise
- * autoconf's AC_C_BIGENDIAN will have tested the host. */
-#if (BYTE_ORDER == LITTLE_ENDIAN) || !defined(WORDS_BIGENDIAN)
-#define byteReverse(buf, len)	/* Nothing */
-#else
-
-/*
- * Note: this code is harmless on little-endian machines.
- */
-static void byteReverse(unsigned char *buf, unsigned longs)
-{
-	uint32 t;
-	do {
-		t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
-		    ((unsigned) buf[1] << 8 | buf[0]);
-		*(uint32 *) buf = t;
-		buf += 4;
-	} while (--longs);
-}
-
-#endif
-
-/*
- * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-static void gdm_md5_init(struct GdmMD5Context *ctx)
-{
-	ctx->buf[0] = 0x67452301;
-	ctx->buf[1] = 0xefcdab89;
-	ctx->buf[2] = 0x98badcfe;
-	ctx->buf[3] = 0x10325476;
-
-	ctx->bits[0] = 0;
-	ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-static void gdm_md5_update(struct GdmMD5Context *ctx,
-		unsigned char const *buf, unsigned len)
-{
-	uint32 t;
-
-	/* Update bitcount */
-
-	t = ctx->bits[0];
-	if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
-		ctx->bits[1]++;	/* Carry from low to high */
-	ctx->bits[1] += len >> 29;
-
-	t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
-
-	/* Handle any leading odd-sized chunks */
-
-	if (t) {
-		unsigned char *p = (unsigned char *) ctx->in + t;
-
-		t = 64 - t;
-		if (len < t) {
-			memcpy(p, buf, len);
-			return;
-		}
-		memcpy(p, buf, t);
-		byteReverse(ctx->in, 16);
-		gdm_md5_transform(ctx->buf, (uint32 *) ctx->in);
-		buf += t;
-		len -= t;
-	}
-
-	/* Process data in 64-byte chunks */
-
-	while (len >= 64) {
-		memcpy(ctx->in, buf, 64);
-		byteReverse(ctx->in, 16);
-		gdm_md5_transform(ctx->buf, (uint32 *) ctx->in);
-		buf += 64;
-		len -= 64;
-	}
-
-	/* Handle any remaining bytes of data. */
-
-	memcpy(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern 
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-static void gdm_md5_final(unsigned char digest[16],
-		struct GdmMD5Context *ctx)
-{
-	unsigned count;
-	unsigned char *p;
-
-	/* Compute number of bytes mod 64 */
-	count = (ctx->bits[0] >> 3) & 0x3F;
-
-	/* Set the first char of padding to 0x80.  This is safe since there is
-	   always at least one byte free */
-	p = ctx->in + count;
-	*p++ = 0x80;
-
-	/* Bytes of padding needed to make 64 bytes */
-	count = 64 - 1 - count;
-
-	/* Pad out to 56 mod 64 */
-	if (count < 8) {
-		/* Two lots of padding:  Pad the first block to 64 bytes */
-		memset(p, 0, count);
-		byteReverse(ctx->in, 16);
-		gdm_md5_transform(ctx->buf, (uint32 *) ctx->in);
-
-		/* Now fill the next block with 56 bytes */
-		memset(ctx->in, 0, 56);
-	} else {
-		/* Pad block to 56 bytes */
-		memset(p, 0, count - 8);
-	}
-	byteReverse(ctx->in, 14);
-
-	/* Append length in bits and transform */
-	((uint32 *) ctx->in)[14] = ctx->bits[0];
-	((uint32 *) ctx->in)[15] = ctx->bits[1];
-
-	gdm_md5_transform(ctx->buf, (uint32 *) ctx->in);
-	byteReverse((unsigned char *) ctx->buf, 4);
-	memcpy(digest, ctx->buf, 16);
-	memset(ctx, 0, sizeof(ctx));	/* In case it's sensitive */
-}
-
-
-/* The four core functions - F1 is optimized somewhat */
-
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1 (z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define gdm_md5_step(f, w, x, y, z, data, s) \
-	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data.  GdmMD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-static void gdm_md5_transform(uint32 buf[4], uint32 const in[16])
-{
-	register uint32 a, b, c, d;
-
-	a = buf[0];
-	b = buf[1];
-	c = buf[2];
-	d = buf[3];
-
-	gdm_md5_step(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
-	gdm_md5_step(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
-	gdm_md5_step(F1, c, d, a, b, in[2] + 0x242070db, 17);
-	gdm_md5_step(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
-	gdm_md5_step(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
-	gdm_md5_step(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
-	gdm_md5_step(F1, c, d, a, b, in[6] + 0xa8304613, 17);
-	gdm_md5_step(F1, b, c, d, a, in[7] + 0xfd469501, 22);
-	gdm_md5_step(F1, a, b, c, d, in[8] + 0x698098d8, 7);
-	gdm_md5_step(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
-	gdm_md5_step(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
-	gdm_md5_step(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
-	gdm_md5_step(F1, a, b, c, d, in[12] + 0x6b901122, 7);
-	gdm_md5_step(F1, d, a, b, c, in[13] + 0xfd987193, 12);
-	gdm_md5_step(F1, c, d, a, b, in[14] + 0xa679438e, 17);
-	gdm_md5_step(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
-	gdm_md5_step(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
-	gdm_md5_step(F2, d, a, b, c, in[6] + 0xc040b340, 9);
-	gdm_md5_step(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
-	gdm_md5_step(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
-	gdm_md5_step(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
-	gdm_md5_step(F2, d, a, b, c, in[10] + 0x02441453, 9);
-	gdm_md5_step(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
-	gdm_md5_step(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
-	gdm_md5_step(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
-	gdm_md5_step(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
-	gdm_md5_step(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
-	gdm_md5_step(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
-	gdm_md5_step(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
-	gdm_md5_step(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
-	gdm_md5_step(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
-	gdm_md5_step(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
-	gdm_md5_step(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
-	gdm_md5_step(F3, d, a, b, c, in[8] + 0x8771f681, 11);
-	gdm_md5_step(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
-	gdm_md5_step(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
-	gdm_md5_step(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
-	gdm_md5_step(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
-	gdm_md5_step(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
-	gdm_md5_step(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
-	gdm_md5_step(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
-	gdm_md5_step(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
-	gdm_md5_step(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
-	gdm_md5_step(F3, b, c, d, a, in[6] + 0x04881d05, 23);
-	gdm_md5_step(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
-	gdm_md5_step(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
-	gdm_md5_step(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
-	gdm_md5_step(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
-	gdm_md5_step(F4, a, b, c, d, in[0] + 0xf4292244, 6);
-	gdm_md5_step(F4, d, a, b, c, in[7] + 0x432aff97, 10);
-	gdm_md5_step(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
-	gdm_md5_step(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
-	gdm_md5_step(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
-	gdm_md5_step(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
-	gdm_md5_step(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
-	gdm_md5_step(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
-	gdm_md5_step(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
-	gdm_md5_step(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
-	gdm_md5_step(F4, c, d, a, b, in[6] + 0xa3014314, 15);
-	gdm_md5_step(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
-	gdm_md5_step(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
-	gdm_md5_step(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
-	gdm_md5_step(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
-	gdm_md5_step(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
-	buf[0] += a;
-	buf[1] += b;
-	buf[2] += c;
-	buf[3] += d;
-}
-
 char *dm_md5(const unsigned char * const buf)
 {
-	struct GdmMD5Context mycontext;
-	unsigned char result[16];
+	GChecksum *checksum;
 	char *md5hash;
-	int i;
 
 	if (buf == NULL) {
 		TRACE(TRACE_ERROR, "received NULL argument");
 		return NULL;
 	}
 
-	md5hash = g_new0(char, 33);
-	if (md5hash == NULL) {
-		TRACE(TRACE_ERROR, "error allocating memory");
-		return NULL;
-	}
-
-	gdm_md5_init(&mycontext);
-	gdm_md5_update(&mycontext, buf, strlen((char *)buf));
-	gdm_md5_final(result, &mycontext);
-
-	for (i = 0; i < 16; i++) {
-		sprintf(&md5hash[i * 2], "%02x", result[i]);
-	}
+	checksum = g_checksum_new(G_CHECKSUM_MD5);
+	g_checksum_update(checksum, buf, strlen((char *)buf));
+	md5hash = g_strdup(g_checksum_get_string(checksum));
+	g_checksum_free(checksum);
 
 	return md5hash;
 }
@@ -324,21 +64,24 @@ char *dm_md5(const unsigned char * const buf)
 /* Always returns an allocation of 18 bytes. */
 char *dm_md5_base64(const unsigned char * const buf)
 {
-	struct GdmMD5Context mycontext;
-	unsigned char result[16];
-	unsigned char base64[24];
+	GChecksum *checksum;
+	guint8 result[32];
+	gsize digest_len = 32;
+	unsigned char base64[32];
 
 	if (buf == NULL) {
 		TRACE(TRACE_ERROR, "received NULL argument");
 		return NULL;
 	}
 
-	gdm_md5_init(&mycontext);
-	gdm_md5_update(&mycontext, buf, strlen((char *)buf));
-	gdm_md5_final(result, &mycontext);
-
 	memset(base64, '\0', sizeof(base64));
-	base64_encode(base64, result, sizeof(result));
+	checksum = g_checksum_new(G_CHECKSUM_MD5);
+	g_checksum_update(checksum, buf, strlen((char *)buf));
+	g_checksum_get_digest(checksum, result, &digest_len);
+
+	base64_encode(base64, (const unsigned char *)result, (int)digest_len);
+
+	g_checksum_free(checksum);
 
 	return g_strdup((char *)base64);
 }
--
cgit v0.8.3-6-g21f6