[Pkg-shadow-commits] r1414 - in upstream/trunk: . lib libmisc src

nekral-guest at alioth.debian.org nekral-guest at alioth.debian.org
Tue Nov 20 09:33:53 UTC 2007


Author: nekral-guest
Date: 2007-11-20 09:33:52 +0000 (Tue, 20 Nov 2007)
New Revision: 1414

Modified:
   upstream/trunk/ChangeLog
   upstream/trunk/lib/getdef.c
   upstream/trunk/lib/prototypes.h
   upstream/trunk/libmisc/salt.c
   upstream/trunk/src/chgpasswd.c
   upstream/trunk/src/chpasswd.c
   upstream/trunk/src/gpasswd.c
   upstream/trunk/src/newusers.c
Log:
* lib/prototypes.h, libmisc/salt.c: Add parameters to
  crypt_make_salt to force the crypt method and number of rounds.
* libmisc/salt.c: Add parameter to SHA_salt_rounds to force the
  number of rounds.
* libmisc/salt.c, lib/getdef.c: ENCRYPT_METHOD and MD5_CRYPT_ENAB
  are needed also when USE_PAM (e.g. for chpasswd).
* src/newusers.c, src/gpasswd.c: Use the new crypt_make_salt prototype.
* src/chpasswd.c, src/chgpasswd.c: Add option -c, --crypt-method
  and -s, --sha-rounds to specify the crypt method and number of
  rounds in case of one of the SHA methods. The new prototype of
  crypt_make_salt simplifies the handling of -m, --md5.


Modified: upstream/trunk/ChangeLog
===================================================================
--- upstream/trunk/ChangeLog	2007-11-20 09:20:34 UTC (rev 1413)
+++ upstream/trunk/ChangeLog	2007-11-20 09:33:52 UTC (rev 1414)
@@ -1,3 +1,17 @@
+2007-11-20  Nicolas François  <nicolas.francois at centraliens.net>
+
+	* lib/prototypes.h, libmisc/salt.c: Add parameters to
+	crypt_make_salt to force the crypt method and number of rounds.
+	* libmisc/salt.c: Add parameter to SHA_salt_rounds to force the
+	number of rounds.
+	* libmisc/salt.c, lib/getdef.c: ENCRYPT_METHOD and MD5_CRYPT_ENAB
+	are needed also when USE_PAM (e.g. for chpasswd).
+	* src/newusers.c, src/gpasswd.c: Use the new crypt_make_salt prototype
+	* src/chpasswd.c, src/chgpasswd.c: Add option -c, --crypt-method
+	and -s, --sha-rounds to specify the crypt method and number of
+	rounds in case of one of the SHA methods. The new prototype of
+	crypt_make_salt simplifies the handling of -m, --md5.
+
 2007-11-19  Nicolas François  <nicolas.francois at centraliens.net>
 
 	* libmisc/salt.c: The salt has a random size (between 8 and 16

Modified: upstream/trunk/lib/getdef.c
===================================================================
--- upstream/trunk/lib/getdef.c	2007-11-20 09:20:34 UTC (rev 1413)
+++ upstream/trunk/lib/getdef.c	2007-11-20 09:33:52 UTC (rev 1414)
@@ -52,6 +52,7 @@
 	{"CONSOLE", NULL},
 	{"CREATE_HOME", NULL},
 	{"DEFAULT_HOME", NULL},
+	{"ENCRYPT_METHOD", NULL},
 	{"ENV_PATH", NULL},
 	{"ENV_SUPATH", NULL},
 	{"ERASECHAR", NULL},
@@ -67,9 +68,12 @@
 	{"LOG_UNKFAIL_ENAB", NULL},
 	{"MAIL_DIR", NULL},
 	{"MAIL_FILE", NULL},
+	{"MD5_CRYPT_ENAB", NULL},
 	{"PASS_MAX_DAYS", NULL},
 	{"PASS_MIN_DAYS", NULL},
 	{"PASS_WARN_AGE", NULL},
+	{"SHA_CRYPT_MAX_ROUNDS", NULL},
+	{"SHA_CRYPT_MIN_ROUNDS", NULL},
 	{"SULOG_FILE", NULL},
 	{"SU_NAME", NULL},
 	{"TTYGROUP", NULL},
@@ -84,7 +88,6 @@
 	{"CHFN_AUTH", NULL},
 	{"CHSH_AUTH", NULL},
 	{"CRACKLIB_DICTPATH", NULL},
-	{"ENCRYPT_METHOD", NULL},
 	{"ENV_HZ", NULL},
 	{"ENVIRON_FILE", NULL},
 	{"ENV_TZ", NULL},
@@ -94,7 +97,6 @@
 	{"LASTLOG_ENAB", NULL},
 	{"LOGIN_STRING", NULL},
 	{"MAIL_CHECK_ENAB", NULL},
-	{"MD5_CRYPT_ENAB", NULL},
 	{"MOTD_FILE", NULL},
 	{"NOLOGINS_FILE", NULL},
 	{"OBSCURE_CHECKS_ENAB", NULL},
@@ -104,8 +106,6 @@
 	{"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/lib/prototypes.h
===================================================================
--- upstream/trunk/lib/prototypes.h	2007-11-20 09:20:34 UTC (rev 1413)
+++ upstream/trunk/lib/prototypes.h	2007-11-20 09:33:52 UTC (rev 1414)
@@ -132,7 +132,7 @@
 extern int do_rlogin (const char *, char *, int, char *, int);
 
 /* salt.c */
-extern char *crypt_make_salt (void);
+extern char *crypt_make_salt (char *meth, void *arg);
 
 /* setugid.c */
 extern int setup_groups (const struct passwd *);

Modified: upstream/trunk/libmisc/salt.c
===================================================================
--- upstream/trunk/libmisc/salt.c	2007-11-20 09:20:34 UTC (rev 1413)
+++ upstream/trunk/libmisc/salt.c	2007-11-20 09:33:52 UTC (rev 1414)
@@ -85,29 +85,33 @@
 /*
  * Return a salt prefix specifying the rounds number for the SHA crypt methods.
  */
-static char *SHA_salt_rounds (void)
+static char *SHA_salt_rounds (int *prefered_rounds)
 {
-	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);
+	static char rounds_prefix[18];
 	long rounds;
 
-	if (-1 == min_rounds && -1 == max_rounds)
-		return "";
+	if (NULL == prefered_rounds) {
+		long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1);
+		long max_rounds = getdef_long ("SHA_CRYPT_MAX_ROUNDS", -1);
 
-	if (-1 == min_rounds)
-		min_rounds = max_rounds;
+		if (-1 == min_rounds && -1 == max_rounds)
+			return "";
 
-	if (-1 == max_rounds)
-		max_rounds = min_rounds;
+		if (-1 == min_rounds)
+			min_rounds = max_rounds;
 
-	if (min_rounds > max_rounds)
-		max_rounds = min_rounds;
+		if (-1 == max_rounds)
+			max_rounds = min_rounds;
 
-	srand (time (NULL));
-	rounds = min_rounds +
-	         (double)rand () * (max_rounds-min_rounds+1)/RAND_MAX;
+		if (min_rounds > max_rounds)
+			max_rounds = min_rounds;
 
+		srand (time (NULL));
+		rounds = min_rounds +
+		         (double)rand () * (max_rounds-min_rounds+1)/RAND_MAX;
+	} else if (0 == *prefered_rounds)
+		return "";
+
 	/* Sanity checks. The libc should also check this, but this
 	 * protects against a rounds_prefix overflow. */
 	if (rounds < ROUNDS_MIN)
@@ -133,8 +137,16 @@
  * (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
+ *
+ * The method can be forced with the meth parameter.
+ * If NULL, the method will be defined according to the MD5_CRYPT_ENAB and
+ * ENCRYPT_METHOD login.defs variables.
+ *
+ * If meth is specified, an additional parameter can be provided.
+ *  * For the SHA256 and SHA512 method, this specifies the number of rounds
+ *    (if not NULL).
  */
-char *crypt_make_salt (void)
+char *crypt_make_salt (char *meth, void *arg)
 {
 	struct timeval tv;
 	/* Max result size for the SHA methods:
@@ -145,41 +157,39 @@
 	 */
 	static char result[40];
 	int max_salt_len = 8;
-	char *method;
+	char *method = "DES";
 
 	result[0] = '\0';
 
-#ifndef USE_PAM
+	if (NULL != meth)
+		method = meth;
+	else
 #ifdef ENCRYPTMETHOD_SELECT
-	if ((method = getdef_str ("ENCRYPT_METHOD")) == NULL) {
+	if ((method = getdef_str ("ENCRYPT_METHOD")) == NULL)
 #endif
-		if (getdef_bool ("MD5_CRYPT_ENAB")) {
-			MAGNUM(result,'1');
-			max_salt_len = 11;
-		}
+		if (getdef_bool ("MD5_CRYPT_ENAB"))
+			method = "MD5";
+
+	if (!strncmp (method, "MD5", 3)) {
+		MAGNUM(result, '1');
+		max_salt_len = 11;
 #ifdef ENCRYPTMETHOD_SELECT
-	} else {
-		if (!strncmp (method, "MD5", 3)) {
-			MAGNUM(result, '1');
-			max_salt_len = 11;
-		} else if (!strncmp (method, "SHA256", 6)) {
-			MAGNUM(result, '5');
-			strcat(result, SHA_salt_rounds());
-			max_salt_len = strlen(result) + SHA_salt_size();
-		} else if (!strncmp (method, "SHA512", 6)) {
-			MAGNUM(result, '6');
-			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"
-				   "Defaulting to DES.\n"),
-				 method);
-			result[0] = '\0';
-		}
+	} else if (!strncmp (method, "SHA256", 6)) {
+		MAGNUM(result, '5');
+		strcat(result, SHA_salt_rounds((int *)arg));
+		max_salt_len = strlen(result) + SHA_salt_size();
+	} else if (!strncmp (method, "SHA512", 6)) {
+		MAGNUM(result, '6');
+		strcat(result, SHA_salt_rounds((int *)arg));
+		max_salt_len = strlen(result) + SHA_salt_size();
+#endif
+	} else if (0 != strncmp (method, "DES", 3)) {
+		fprintf (stderr,
+			 _("Invalid ENCRYPT_METHOD value: '%s'.\n"
+			   "Defaulting to DES.\n"),
+			 method);
+		result[0] = '\0';
 	}
-#endif				/* ENCRYPTMETHOD_SELECT */
-#endif				/* USE_PAM */
 
 	/*
 	 * Concatenate a pseudo random salt.

Modified: upstream/trunk/src/chgpasswd.c
===================================================================
--- upstream/trunk/src/chgpasswd.c	2007-11-20 09:20:34 UTC (rev 1413)
+++ upstream/trunk/src/chgpasswd.c	2007-11-20 09:33:52 UTC (rev 1414)
@@ -50,9 +50,14 @@
  * Global variables
  */
 static char *Prog;
+static int cflg = 0;
 static int eflg = 0;
 static int md5flg = 0;
+static int sflg = 0;
 
+static char *crypt_method = NULL;
+static int sha_rounds = 5000;
+
 #ifdef SHADOWGRP
 static int is_shadow_grp;
 #endif
@@ -68,14 +73,36 @@
 	fprintf (stderr, _("Usage: chgpasswd [options]\n"
 			   "\n"
 			   "Options:\n"
+			   "  -c, --crypt-method	the crypt method (one of %s)\n"
 			   "  -e, --encrypted	supplied passwords are encrypted\n"
 			   "  -h, --help		display this help message and exit\n"
 			   "  -m, --md5		use MD5 encryption instead DES when the supplied\n"
 			   "			passwords are not encrypted\n"
-			   "\n"));
+			   "\n"),
+#ifndef ENCRYPTMETHOD_SELECT
+			 "DES MD5"
+#else
+			 "DES MD5 SHA256 SHA512"
+#endif
+			 );
 	exit (1);
 }
 
+static long getnumber (const char *numstr)
+{
+	long val;
+	char *errptr;
+
+	val = strtol (numstr, &errptr, 10);
+	if (*errptr || errno == ERANGE) {
+		fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
+		         numstr);
+		exit (1);
+	}
+
+	return val;
+}
+
 int main (int argc, char **argv)
 {
 	char buf[BUFSIZ];
@@ -111,16 +138,22 @@
 		int option_index = 0;
 		int c;
 		static struct option long_options[] = {
+			{"crypt-method", required_argument, NULL, 'c'},
 			{"encrypted", no_argument, NULL, 'e'},
 			{"help", no_argument, NULL, 'h'},
 			{"md5", no_argument, NULL, 'm'},
+			{"sha-rounds", required_argument, NULL, 's'},
 			{NULL, 0, NULL, '\0'}
 		};
 
 		while ((c =
-			getopt_long (argc, argv, "ehm", long_options,
+			getopt_long (argc, argv, "c:ehms:", long_options,
 				     &option_index)) != -1) {
 			switch (c) {
+			case 'c':
+				cflg = 1;
+				crypt_method = optarg;
+				break;
 			case 'e':
 				eflg = 1;
 				break;
@@ -130,6 +163,10 @@
 			case 'm':
 				md5flg = 1;
 				break;
+			case 's':
+				sflg = 1;
+				sha_rounds = getnumber(optarg);
+				break;
 			case 0:
 				/* long option */
 				break;
@@ -140,6 +177,34 @@
 		}
 	}
 
+	/* validate options */
+	if (sflg && !cflg) {
+		fprintf (stderr,
+			 _("%s: %s flag is ONLY allowed with the %s flag\n"),
+			 Prog, "-s", "-c");
+		usage ();
+	}
+	if (md5flg && cflg) {
+		fprintf (stderr,
+			 _("%s: the -m and -c flags are exclusive\n"),
+			 Prog);
+		usage ();
+	}
+	if (cflg) {
+		if (0 != strcmp (method, "DES") &&
+		    0 != strcmp (method, "MD5") &&
+#ifdef ENCRYPTMETHOD_SELECT
+		    0 != strcmp (method, "SHA256") &&
+		    0 != strcmp (method, "SHA512")
+#endif
+		    ) {
+			fprintf (stderr,
+			 _("%s: unsupported crypt method: %s\n"),
+			 Prog, method);
+			usage ();
+		}
+	}
+
 #ifdef USE_PAM
 	retval = PAM_SUCCESS;
 
@@ -245,18 +310,16 @@
 		}
 		newpwd = cp;
 		if (!eflg) {
-			if (md5flg) {
-				char md5salt[12] = "$1$";
-				char *salt = crypt_make_salt ();
-
-				if (strncmp (salt, "$1$", 3) == 0) {
-					strncpy (md5salt, salt, 11);
-				} else {
-					strncat (md5salt, salt, 8);
-				}
-				cp = pw_encrypt (newpwd, md5salt);
+			void *arg = NULL;
+			if (md5flg)
+				crypt_method = "MD5";
+			else if (crypt_method != NULL) {
+				if (sflg)
+					arg = &sha_rounds;
 			} else
-				cp = pw_encrypt (newpwd, crypt_make_salt ());
+				crypt_method = "DES";
+			cp = pw_encrypt (newpwd,
+			                 crypt_make_salt(crypt_method, arg));
 		}
 
 		/*

Modified: upstream/trunk/src/chpasswd.c
===================================================================
--- upstream/trunk/src/chpasswd.c	2007-11-20 09:20:34 UTC (rev 1413)
+++ upstream/trunk/src/chpasswd.c	2007-11-20 09:33:52 UTC (rev 1414)
@@ -49,9 +49,14 @@
  * Global variables
  */
 static char *Prog;
+static int cflg = 0;
 static int eflg = 0;
 static int md5flg = 0;
+static int sflg = 0;
 
+static char *crypt_method = NULL;
+static int sha_rounds = 5000;
+
 static int is_shadow_pwd;
 
 /* local function prototypes */
@@ -65,14 +70,36 @@
 	fprintf (stderr, _("Usage: chpasswd [options]\n"
 			   "\n"
 			   "Options:\n"
+			   "  -c, --crypt-method	the crypt method (one of %s)\n"
 			   "  -e, --encrypted	supplied passwords are encrypted\n"
 			   "  -h, --help		display this help message and exit\n"
 			   "  -m, --md5		use MD5 encryption instead DES when the supplied\n"
 			   "			passwords are not encrypted\n"
-			   "\n"));
+			   "\n"),
+#ifndef ENCRYPTMETHOD_SELECT
+			 "DES MD5"
+#else
+			 "DES MD5 SHA256 SHA512"
+#endif
+			 );
 	exit (E_USAGE);
 }
 
+static long getnumber (const char *numstr)
+{
+	long val;
+	char *errptr;
+
+	val = strtol (numstr, &errptr, 10);
+	if (*errptr || errno == ERANGE) {
+		fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
+		         numstr);
+		exit (1);
+	}
+
+	return val;
+}
+
 int main (int argc, char **argv)
 {
 	char buf[BUFSIZ];
@@ -105,16 +132,22 @@
 		int option_index = 0;
 		int c;
 		static struct option long_options[] = {
+			{"crypt-method", required_argument, NULL, 'c'},
 			{"encrypted", no_argument, NULL, 'e'},
 			{"help", no_argument, NULL, 'h'},
 			{"md5", no_argument, NULL, 'm'},
+			{"sha-rounds", required_argument, NULL, 's'},
 			{NULL, 0, NULL, '\0'}
 		};
 
 		while ((c =
-			getopt_long (argc, argv, "ehm", long_options,
+			getopt_long (argc, argv, "c:ehms:", long_options,
 				     &option_index)) != -1) {
 			switch (c) {
+			case 'c':
+				cflg = 1;
+				crypt_method = optarg;
+				break;
 			case 'e':
 				eflg = 1;
 				break;
@@ -124,6 +157,10 @@
 			case 'm':
 				md5flg = 1;
 				break;
+			case 's':
+				sflg = 1;
+				sha_rounds = getnumber(optarg);
+				break;
 			case 0:
 				/* long option */
 				break;
@@ -134,6 +171,34 @@
 		}
 	}
 
+	/* validate options */
+	if (sflg && !cflg) {
+		fprintf (stderr,
+			 _("%s: %s flag is ONLY allowed with the %s flag\n"),
+			 Prog, "-s", "-c");
+		usage ();
+	}
+	if (md5flg && cflg) {
+		fprintf (stderr,
+			 _("%s: the -m and -c flags are exclusive\n"),
+			 Prog);
+		usage ();
+	}
+	if (cflg) {
+		if (0 != strcmp (method, "DES") &&
+		    0 != strcmp (method, "MD5") &&
+#ifdef ENCRYPTMETHOD_SELECT
+		    0 != strcmp (method, "SHA256") &&
+		    0 != strcmp (method, "SHA512")
+#endif
+		    ) {
+			fprintf (stderr,
+			 _("%s: unsupported crypt method: %s\n"),
+			 Prog, method);
+			usage ();
+		}
+	}
+
 #ifdef USE_PAM
 	retval = PAM_SUCCESS;
 
@@ -241,18 +306,16 @@
 		}
 		newpwd = cp;
 		if (!eflg) {
-			if (md5flg) {
-				char md5salt[12] = "$1$";
-				char *salt = crypt_make_salt ();
-
-				if (strncmp (salt, "$1$", 3) == 0) {
-					strncpy (md5salt, salt, 11);
-				} else {
-					strncat (md5salt, salt, 8);
-				}
-				cp = pw_encrypt (newpwd, salt);
+			void *arg = NULL;
+			if (md5flg)
+				crypt_method = "MD5";
+			else if (crypt_method != NULL) {
+				if (sflg)
+					arg = &sha_rounds;
 			} else
-				cp = pw_encrypt (newpwd, crypt_make_salt ());
+				crypt_method = "DES";
+			cp = pw_encrypt (newpwd,
+			                 crypt_make_salt(crypt_method, arg));
 		}
 
 		/*

Modified: upstream/trunk/src/gpasswd.c
===================================================================
--- upstream/trunk/src/gpasswd.c	2007-11-20 09:20:34 UTC (rev 1413)
+++ upstream/trunk/src/gpasswd.c	2007-11-20 09:33:52 UTC (rev 1414)
@@ -607,7 +607,7 @@
 		exit (1);
 	}
 
-	cp = pw_encrypt (pass, crypt_make_salt ());
+	cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL));
 	memzero (pass, sizeof pass);
 #ifdef SHADOWGRP
 	if (is_shadowgrp)

Modified: upstream/trunk/src/newusers.c
===================================================================
--- upstream/trunk/src/newusers.c	2007-11-20 09:20:34 UTC (rev 1413)
+++ upstream/trunk/src/newusers.c	2007-11-20 09:33:52 UTC (rev 1414)
@@ -214,7 +214,7 @@
 
 static void update_passwd (struct passwd *pwd, const char *passwd)
 {
-	pwd->pw_passwd = pw_encrypt (passwd, crypt_make_salt ());
+	pwd->pw_passwd = pw_encrypt (passwd, crypt_make_salt (NULL, NULL));
 }
 
 /*
@@ -241,7 +241,8 @@
 	 */
 	if ((sp = spw_locate (pwd->pw_name))) {
 		spent = *sp;
-		spent.sp_pwdp = pw_encrypt (passwd, crypt_make_salt ());
+		spent.sp_pwdp = pw_encrypt (passwd,
+		                            crypt_make_salt (NULL, NULL));
 		return !spw_update (&spent);
 	}
 
@@ -261,7 +262,7 @@
 	 * shadow password file entry.
 	 */
 	spent.sp_namp = pwd->pw_name;
-	spent.sp_pwdp = pw_encrypt (passwd, crypt_make_salt ());
+	spent.sp_pwdp = pw_encrypt (passwd, crypt_make_salt (NULL, NULL));
 	spent.sp_lstchg = time ((time_t *) 0) / SCALE;
 	spent.sp_min = getdef_num ("PASS_MIN_DAYS", 0);
 	/* 10000 is infinity this week */




More information about the Pkg-shadow-commits mailing list