[Pkg-shadow-commits] r1412 - in upstream/trunk: . etc lib libmisc

nekral-guest at alioth.debian.org nekral-guest at alioth.debian.org
Tue Nov 20 00:05:54 UTC 2007


Author: nekral-guest
Date: 2007-11-20 00:05:54 +0000 (Tue, 20 Nov 2007)
New Revision: 1412

Modified:
   upstream/trunk/ChangeLog
   upstream/trunk/etc/login.defs
   upstream/trunk/lib/getdef.c
   upstream/trunk/libmisc/salt.c
Log:
* libmisc/salt.c: The salt has a random size (between 8 and 16
  bytes).
* lib/getdef.c, etc/login.defs: Add definitions for
  SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS.
* libmisc/salt.c: Use SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS
  to add a random number of rounds if needed.


Modified: upstream/trunk/ChangeLog
===================================================================
--- upstream/trunk/ChangeLog	2007-11-19 22:34:48 UTC (rev 1411)
+++ upstream/trunk/ChangeLog	2007-11-20 00:05:54 UTC (rev 1412)
@@ -1,5 +1,14 @@
 2007-11-19  Nicolas François  <nicolas.francois at centraliens.net>
 
+	* libmisc/salt.c: The salt has a random size (between 8 and 16
+	bytes).
+	* lib/getdef.c, etc/login.defs: Add definitions for
+	SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS.
+	* libmisc/salt.c: Use SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS
+	to add a random number of rounds if needed.
+
+2007-11-19  Nicolas François  <nicolas.francois at centraliens.net>
+
 	* libmisc/salt.c (MAGNUM): Terminate the array with nul (the array
 	is then used with strcat).
 	* libmisc/salt.c (crypt_make_salt): Initialize result[0] to nul at

Modified: upstream/trunk/etc/login.defs
===================================================================
--- upstream/trunk/etc/login.defs	2007-11-19 22:34:48 UTC (rev 1411)
+++ upstream/trunk/etc/login.defs	2007-11-20 00:05:54 UTC (rev 1412)
@@ -289,6 +289,22 @@
 #ENCRYPT_METHOD DES
 
 #
+# Only works if ENCRYPT_METHOD is set to SHA256 or SHA512.
+#
+# Define the number of SHA rounds.
+# With a lot of rounds, it is more difficult to brute forcing the password.
+# But note also that it more CPU resources will be needed to authenticate
+# users.
+#
+# If not specified, the libc will choose the default number of rounds (5000).
+# The values must be inside the 1000-999999999 range.
+# If only one of the MIN or MAX values is set, then this value will be used.
+# If MIN > MAX, the highest value will be used.
+#
+# SHA_CRYPT_MIN_ROUNDS 5000
+# SHA_CRYPT_MAX_ROUNDS 5000
+
+#
 # List of groups to add to the user's supplementary group set
 # when logging in on the console (as determined by the CONSOLE
 # setting).  Default is none.

Modified: upstream/trunk/lib/getdef.c
===================================================================
--- upstream/trunk/lib/getdef.c	2007-11-19 22:34:48 UTC (rev 1411)
+++ upstream/trunk/lib/getdef.c	2007-11-20 00:05:54 UTC (rev 1412)
@@ -104,6 +104,8 @@
 	{"PASS_MIN_LEN", NULL},
 	{"PORTTIME_CHECKS_ENAB", NULL},
 	{"QUOTAS_ENAB", NULL},
+	{"SHA_CRYPT_MAX_ROUNDS", NULL},
+	{"SHA_CRYPT_MIN_ROUNDS", NULL},
 	{"SU_WHEEL_ONLY", NULL},
 	{"ULIMIT", NULL},
 #endif

Modified: upstream/trunk/libmisc/salt.c
===================================================================
--- upstream/trunk/libmisc/salt.c	2007-11-19 22:34:48 UTC (rev 1411)
+++ upstream/trunk/libmisc/salt.c	2007-11-20 00:05:54 UTC (rev 1412)
@@ -53,19 +53,91 @@
 #endif /* !HAVE_L64A */
 
 /*
+ * Add the salt prefix.
+ */
+#define MAGNUM(array,ch)	(array)[0]= (array)[2] = '$',\
+				(array)[1]=(ch),\
+				(array)[2]='\0'
+
+/*
+ * Return the salt size.
+ * The size of the salt string is between 8 and 16 bytes for the SHA crypt
+ * methods.
+ */
+static unsigned int SHA_salt_size (void)
+{
+	return 8 + 8*rand ()/(RAND_MAX+1);
+}
+
+/* ! Arguments evaluated twice ! */
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+
+/* Default number of rounds if not explicitly specified.  */
+#define ROUNDS_DEFAULT 5000
+/* Minimum number of rounds.  */
+#define ROUNDS_MIN 1000
+/* Maximum number of rounds.  */
+#define ROUNDS_MAX 999999999
+
+/*
+ * Return a salt prefix specifying the rounds number for the SHA crypt methods.
+ */
+static char *SHA_salt_rounds (void)
+{
+	static char *rounds_prefix[18];
+	long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1);
+	long max_rounds = getdef_long ("SHA_CRYPT_MAX_ROUNDS", -1);
+	long rounds;
+
+	if (-1 == min_rounds && -1 == max_rounds)
+		return "";
+
+	if (-1 == min_rounds)
+		min_rounds = max_rounds;
+
+	if (-1 == max_rounds)
+		max_rounds = min_rounds;
+
+	if (min_rounds > max_rounds)
+		max_rounds = min_rounds;
+
+	rounds = min_rounds + (max_rounds - min_rounds)*rand ()/(RAND_MAX+1);
+
+	/* Sanity checks. The libc should also check this, but this
+	 * protects against a rounds_prefix overflow. */
+	if (rounds < ROUNDS_MIN)
+		rounds = ROUNDS_MIN;
+
+	if (rounds > ROUNDS_MAX)
+		rounds = ROUNDS_MAX;
+
+	snprintf (rounds_prefix, 18, "rounds=%ld$", rounds);
+
+	/* Sanity checks. That should not be necessary. */
+	rounds_prefix[17] = '\0';
+	if ('$' != rounds_prefix[16])
+		rounds_prefix[17] = '$';
+
+	return rounds_prefix;
+}
+
+/*
  * Generate 8 base64 ASCII characters of random salt.  If MD5_CRYPT_ENAB
  * in /etc/login.defs is "yes", the salt string will be prefixed by "$1$"
  * (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible
  * version of crypt() instead of the standard one.
+ * Other methods can be set with ENCRYPT_METHOD
  */
-
-#define MAGNUM(array,ch)	(array)[0]= (array)[2] = '$',\
-				(array)[1]=(ch),\
-				(array)[2]='\0'
-
 char *crypt_make_salt (void)
 {
 	struct timeval tv;
+	/* Max result size for the SHA methods:
+	 *  +3		$5$
+	 *  +17		rounds=999999999$
+	 *  +16		salt
+	 *  +1		\0
+	 */
 	static char result[40];
 	int max_salt_len = 8;
 	char *method;
@@ -87,10 +159,12 @@
 			max_salt_len = 11;
 		} else if (!strncmp (method, "SHA256", 6)) {
 			MAGNUM(result, '5');
-			max_salt_len = 11; /* XXX: should not be fixed */
+			strcat(result, SHA_salt_rounds());
+			max_salt_len = strlen(result) + SHA_salt_size();
 		} else if (!strncmp (method, "SHA512", 6)) {
 			MAGNUM(result, '6');
-			max_salt_len = 11; /* XXX: should not be fixed */
+			strcat(result, SHA_salt_rounds());
+			max_salt_len = strlen(result) + SHA_salt_size();
 		} else if (0 != strncmp (method, "DES", 3)) {
 			fprintf (stderr,
 				 _("Invalid ENCRYPT_METHOD value: '%s'.\n"
@@ -101,12 +175,14 @@
 	}
 #endif				/* ENCRYPTMETHOD_SELECT */
 #endif				/* USE_PAM */
+
 	/*
-	 * Generate 8 chars of salt, the old crypt() will use only first 2.
+	 * Concatenate a pseudo random salt.
 	 */
 	gettimeofday (&tv, (struct timezone *) 0);
-	strcat (result, l64a (tv.tv_usec));
-	strcat (result, l64a (tv.tv_sec + getpid () + clock ()));
+	strncat (result, sizeof(result), l64a (tv.tv_usec));
+	strncat (result, sizeof(result),
+		 l64a (tv.tv_sec + getpid () + clock ()));
 
 	if (strlen (result) > max_salt_len)	/* magic+salt */
 		result[max_salt_len] = '\0';




More information about the Pkg-shadow-commits mailing list