On Fri, Apr 10, 2009 at 02:38:26PM +0200, m...@linux.it wrote:
> On Apr 09, Nicolas François <nicolas.franc...@centraliens.net> wrote:
> 
> > In shadow, I had to use gettimeofday(&tv, NULL);
> > srandom (tv.tv_sec + tv.tv_usec) because many passwords had to be
> > generated per second and by the same process.
> I implemented both this and support for /dev/urandom, the patch is
> available at http://www.bofh.it/~md/debian/whois.diff .
> 
> OTOH I do not understand the point of using tv.tv_sec, I wonder if this
> could be a problem on systems with 64 bit integers (whois aims to be
> portable to everything UNIX and more).

I'm not sure it's really necessary.
But at least it should protect against less precise clocks which would
always set to 0 the less significant bits of tv.tv_usec.


BTW, here is the patch to support variable length salts.
The generated salts are always generated with the longest salt possible,
but when the salt is provided on the command line, the given salt is
accepted if its length is between the minimum and the maximum length.

The length of the salts in methods was changed by a minimum length and a
maximum length.

Best Regards,
-- 
Nekral
diff -rauN ../orig/whois-4.7.32/mkpasswd.c ./whois-4.7.32/mkpasswd.c
--- ../orig/whois-4.7.32/mkpasswd.c	2008-12-09 01:11:51.000000000 +0100
+++ ./whois-4.7.32/mkpasswd.c	2009-04-10 21:49:55.739224624 +0200
@@ -65,39 +65,40 @@
 struct crypt_method {
     const char *method;		/* short name used by the command line option */
     const char *prefix;		/* salt prefix */
-    const unsigned int len;	/* salt lenght */
+    const unsigned int minlen;	/* salt minimum length */
+    const unsigned int maxlen;	/* salt maximum length */
     const unsigned int rounds;	/* supports a variable number of rounds */
     const char *desc;		/* long description for the methods list */
 };
 
 static const struct crypt_method methods[] = {
-    /* method		prefix	len rounds description */
-    { "des",		"",	2,  0,
+    /* method		prefix	minlen,	maxlen	rounds description */
+    { "des",		"",	2,	2,	0,
 	N_("standard 56 bit DES-based crypt(3)") },
-    { "md5",		"$1$",	8,  0, "MD5" },
+    { "md5",		"$1$",	8,	8,	0, "MD5" },
 #if defined FreeBSD
-    { "bf",		"$2$",  22, 0, "Blowfish (FreeBSD)" },
+    { "bf",		"$2$",  22,	22,	0, "Blowfish (FreeBSD)" },
 #endif
 #if defined OpenBSD || defined HAVE_XCRYPT
-    { "bf",		"$2a$", 22, 1, "Blowfish" },
+    { "bf",		"$2a$", 22,	22,	1, "Blowfish" },
 #endif
 #if defined FreeBSD
-    { "nt",		"$3$",   0, 0, "NT-Hash" },
+    { "nt",		"$3$",   0,	0,	0, "NT-Hash" },
 #endif
 #if defined HAVE_SHA_CRYPT
     /* http://people.redhat.com/drepper/SHA-crypt.txt */
-    { "sha-256",	"$5$",	16, 1, "SHA-256" },
-    { "sha-512",	"$6$",	16, 1, "SHA-512" },
+    { "sha-256",	"$5$",	8,	16,	1, "SHA-256" },
+    { "sha-512",	"$6$",	8,	16,	1, "SHA-512" },
 #endif
     /* http://www.crypticide.com/dropsafe/article/1389 */
 /* proper support is hard since solaris >= 9 supports pluggable methods
 #if defined __SVR4 && defined __sun
-    { "sunmd5",		"$md5$", ?, 1, "SunMD5" },
+    { "sunmd5",		"$md5$", ?,	?,	1, "SunMD5" },
 */
 #if defined HAVE_XCRYPT
-    { "sha",		"{SHA}", 0, 0, "SHA-1" },
+    { "sha",		"{SHA}", 0,	0,	0, "SHA-1" },
 #endif
-    { NULL,		NULL,	 0, 0, NULL }
+    { NULL,		NULL,	 0,	0,	0, NULL }
 };
 
 void generate_salt(char *const buf, const unsigned int len);
@@ -110,7 +111,8 @@
 {
     int ch, i;
     int password_fd = -1;
-    unsigned int salt_len = 0;
+    unsigned int salt_minlen = 0;
+    unsigned int salt_maxlen = 0;
     unsigned int rounds_support = 0;
     const char *salt_prefix = NULL;
     const char *salt_arg = NULL;
@@ -140,7 +142,8 @@
 	    for (i = 0; methods[i].method != NULL; i++)
 		if (strcaseeq(methods[i].method, optarg)) {
 		    salt_prefix = methods[i].prefix;
-		    salt_len = methods[i].len;
+		    salt_minlen = methods[i].minlen;
+		    salt_maxlen = methods[i].maxlen;
 		    rounds_support = methods[i].rounds;
 		    break;
 		}
@@ -203,7 +206,8 @@
 
     /* default: DES password */
     if (!salt_prefix) {
-	salt_len = methods[0].len;
+	salt_minlen = methods[0].minlen;
+	salt_maxlen = methods[0].maxlen;
 	salt_prefix = methods[0].prefix;
     }
 
@@ -219,11 +223,15 @@
 
     if (salt_arg) {
 	unsigned int c = strlen(salt_arg);
-	/* XXX: should support methods which support variable-length salts */
-	if (c != salt_len) {
-	    fprintf(stderr,
-		    _("Wrong salt length: %d byte(s) when %d expected.\n"),
-		    c, salt_len);
+	if (c < salt_minlen || c > salt_maxlen) {
+	    if (salt_minlen == salt_maxlen)
+		fprintf(stderr,
+			_("Wrong salt length: %d byte(s) when %d expected.\n"),
+			c, salt_maxlen);
+	    else
+		fprintf(stderr,
+			_("Wrong salt length: %d byte(s) when %d <= ... <= %d expected.\n"),
+			c, salt_minlen, salt_maxlen);
 	    exit(1);
 	}
 	while (c-- > 0) {
@@ -252,11 +260,11 @@
 	free(entropy);
 #else
 	salt = NOFAIL(malloc(strlen(salt_prefix) + strlen(rounds_str)
-		+ salt_len + 1));
+		+ salt_maxlen + 1));
 	*salt = '\0';
 	strcat(salt, salt_prefix);
 	strcat(salt, rounds_str);
-	generate_salt(salt + strlen(salt), salt_len);
+	generate_salt(salt + strlen(salt), salt_maxlen);
 #endif
     }
 

Reply via email to