[Dovecot] weakness in hash salt generation

Joshua Goodall joshua at roughtrade.net
Sat Jul 24 04:49:12 EEST 2004


On Fri, Jul 23, 2004 at 09:06:05PM +0300, Timo Sirainen wrote:
> So it seems. But how did you notice it? I don't think those functions 
> are ever called by Dovecot itself? They're there just in case some day 
> they would be useful..

They're useful now.  Reason attached, a first draft of dovecotpw.c.
Only tested on FreeBSD 5-CURRENT.

Regards
Joshua.

-- 
Joshua Goodall                           "as modern as tomorrow afternoon"
joshua at roughtrade.net                                       - FW109
-------------- next part --------------
diff -u -r1.1 dovecotpw.c
--- src/util/dovecotpw.c	Thu Jan  1 10:00:00 1970
+++ src/util/dovecotpw.c	Sat Jul 24 11:45:16 2004
@@ -0,0 +1,122 @@
+/* Copyright (C) 2004 Joshua Goodall */
+
+#include "lib.h"
+#include "password-scheme.h"
+#include "randgen.h"
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define VERIFY_HASH 1
+
+#define DEFAULT_SCHEME "HMAC-MD5"
+
+#define STRWIPE(s) do {			\
+	char *c;			\
+	for (c = s; *c != '\0'; c++)	\
+		*c = '\0';		\
+} while (0)
+	
+static void
+usage(const char *s)
+{
+	fprintf(stderr, "usage: %s [-s scheme] [-p plaintext] [-u user]\n", s);
+	fprintf(stderr, "  -s scheme\tpassword scheme\n");
+	fprintf(stderr, "  -p plaintext\tnew password\n");
+	fprintf(stderr, "  -u user\tusername (if scheme uses it)\n");
+
+	exit(1);
+}
+
+int main(int argc, char *argv[] __attr_unused__)
+{
+	extern char *optarg;
+	extern int optind;
+	const char *hash = NULL;
+	const char *user = NULL;
+	char *scheme = NULL;
+	char *plaintext = NULL;
+	char ch;
+
+	lib_init();
+	random_init();
+	password_schemes_init();
+	
+	while ((ch = getopt(argc, argv, "s:p:u:")) != -1) {
+		switch (ch) {
+		case 's':
+			scheme = strdup(optarg);
+			break;
+		case 'p':
+			plaintext = strdup(optarg);
+			STRWIPE(optarg);
+		case 'u':
+			user = strdup(optarg);
+			break;
+		case '?':
+		default:
+			usage(basename(*argv));
+		}
+	}
+
+	if (argc != optind)
+		usage(basename(*argv));
+
+	if (scheme == NULL)
+		scheme = strdup(DEFAULT_SCHEME);
+	else {
+		char *c;
+		for (c = scheme; *c != '\0'; c++)
+			*c = toupper(*c);
+	}
+
+
+	while (plaintext == NULL) {
+		char *check;
+		static int lives = 3;
+
+		plaintext = strdup(getpass("Enter new password: "));
+		check = strdup(getpass("Retype new password: "));
+		if (strcmp(plaintext, check) != 0) {
+			fprintf(stderr, "Passwords don't match!\n");
+			if (--lives == 0)
+				exit(1);
+			STRWIPE(plaintext);
+			STRWIPE(check);
+			free(plaintext);
+			plaintext = NULL;
+		}
+	}
+
+	if ((hash = password_generate(plaintext, user, scheme)) == NULL) {
+		fprintf(stderr, "error generating password hash\n");
+		exit(1);
+	} else
+#ifdef VERIFY_HASH
+	{
+		char *checkscheme, *checkpass;
+
+		asprintf(&checkpass, "{%s}%s\n", scheme, hash);
+		checkscheme = password_get_scheme(&checkpass);
+
+		if (strcmp(scheme, checkscheme) != 0) {
+			fprintf(stderr, "reverse scheme lookup check failed\n");
+			exit(2);
+		}
+		if (password_verify(plaintext, checkpass, checkscheme, user) != 0) {
+			fprintf(stderr, "reverse password verification check failed\n");
+			exit(2);
+		}
+
+		printf("{%s}%s (verified)\n", scheme, hash);
+	}
+#else
+		printf("{%s}%s\n", scheme, hash);
+#endif
+        return 0;
+}
diff -u -r1.2 Makefile.am
--- src/util/Makefile.am	20 Aug 2003 23:26:37 -0000	1.2
+++ src/util/Makefile.am	24 Jul 2004 01:43:40 -0000
@@ -1,12 +1,25 @@
 pkglibexecdir = $(libexecdir)/dovecot
 
 pkglibexec_PROGRAMS = rawlog
+sbin_PROGRAMS = dovecotpw
 
 INCLUDES = \
-	-I$(top_srcdir)/src/lib
+	-I$(top_srcdir)/src/lib \
+	-I$(top_srcdir)/src/auth
 
 rawlog_LDADD = \
 	../lib/liblib.a
 
 rawlog_SOURCES = \
 	rawlog.c
+
+dovecotpw_LDADD = \
+	../lib/liblib.a \
+	../auth/password-scheme.o \
+	../auth/password-scheme-cram-md5.o \
+	../auth/password-scheme-md5crypt.o \
+	../auth/mycrypt.o \
+	$(AUTH_LIBS)
+
+dovecotpw_SOURCES = \
+	dovecotpw.c
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
URL: <http://dovecot.org/pipermail/dovecot/attachments/20040724/e48c954e/attachment-0001.bin>


More information about the dovecot mailing list