From 9aa40bb96daed560b1bbef388c42d1103081a033 Mon Sep 17 00:00:00 2001
From: nekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Date: Tue, 20 Nov 2007 20:00:16 +0000
Subject: [PATCH] * libmisc/obscure.c, libmisc/salt.c, src/passwd.c: Match DES,
 MD5,   SHA256, and SHA512 exactly (not only the first 3/6 chars). *
 libmisc/salt.c (SHA_salt_rounds): Set rounds to the specified  
 prefered_rounds value, if specified. * src/gpasswd.c, libmisc/salt.c: Fix
 compilation warnings (use   size_t for lengths). * src/chpasswd.c,
 src/chgpasswd.c: Add missing parenthesis.

---
 ChangeLog         | 10 ++++++++++
 lib/encrypt.c     | 23 +++++++++++++++++++++++
 libmisc/obscure.c |  6 +++---
 libmisc/salt.c    | 12 +++++++-----
 src/chgpasswd.c   |  2 +-
 src/chpasswd.c    |  2 +-
 src/gpasswd.c     |  2 +-
 src/passwd.c      |  6 +++---
 8 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1c0defe3..0b9f1636 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-11-20  Nicolas François  <nicolas.francois@centraliens.net>
+
+	* libmisc/obscure.c, libmisc/salt.c, src/passwd.c: Match DES, MD5,
+	SHA256, and SHA512 exactly (not only the first 3/6 chars).
+	* libmisc/salt.c (SHA_salt_rounds): Set rounds to the specified
+	prefered_rounds value, if specified.
+	* src/gpasswd.c, libmisc/salt.c: Fix compilation warnings (use
+	size_t for lengths).
+	* src/chpasswd.c, src/chgpasswd.c: Add missing parenthesis.
+
 2007-11-20  Nicolas François  <nicolas.francois@centraliens.net>
 
 	* man/sv, man/de, man/fr, man/pl, man/ru, man/it: Ignore the
diff --git a/lib/encrypt.c b/lib/encrypt.c
index 44f04362..539ba034 100644
--- a/lib/encrypt.c
+++ b/lib/encrypt.c
@@ -49,6 +49,29 @@ char *pw_encrypt (const char *clear, const char *salt)
 		perror ("crypt");
 		exit (1);
 	}
+	if (salt && salt[0] == '$' && strlen (cp) <= 13)
+	{
+		/* The crypt algorithm was not recognized by libcrypt */
+		char *method = "$1$";
+		switch (salt[1])
+		{
+			case '1':
+				method = "MD5";
+				break;
+			case '5':
+				method = "SHA256";
+				break;
+			case '6':
+				method = "SHA512";
+				break;
+			default:
+				method[1] = salt[1];
+		}
+		fprintf (stderr,
+			 _("Unknown crypt method (%s)\n"),
+			  method);
+		exit (1);
+	}
 	if (strlen (cp) != 13)
 		return cp;	/* nonstandard crypt() in libc, better bail out */
 	strcpy (cipher, cp);
diff --git a/libmisc/obscure.c b/libmisc/obscure.c
index d45b084f..a87d7ee4 100644
--- a/libmisc/obscure.c
+++ b/libmisc/obscure.c
@@ -245,9 +245,9 @@ static const char *password_check (const char *old, const char *new,
 #ifdef ENCRYPTMETHOD_SELECT
 	} else {
 
-		if (!strncmp (result, "MD5"   , 3) ||
-		    !strncmp (result, "SHA256", 6) ||
-		    !strncmp (result, "SHA512", 6))
+		if (!strcmp (result, "MD5") ||
+		    !strcmp (result, "SHA256") ||
+		    !strcmp (result, "SHA512"))
 			return NULL;
 
 	}
diff --git a/libmisc/salt.c b/libmisc/salt.c
index 8ee0dcbb..2f1a4be2 100644
--- a/libmisc/salt.c
+++ b/libmisc/salt.c
@@ -111,6 +111,8 @@ static char *SHA_salt_rounds (int *prefered_rounds)
 		         (double)rand () * (max_rounds-min_rounds+1)/RAND_MAX;
 	} else if (0 == *prefered_rounds)
 		return "";
+	else
+		rounds = *prefered_rounds;
 
 	/* Sanity checks. The libc should also check this, but this
 	 * protects against a rounds_prefix overflow. */
@@ -156,7 +158,7 @@ char *crypt_make_salt (char *meth, void *arg)
 	 *  +1		\0
 	 */
 	static char result[40];
-	int max_salt_len = 8;
+	size_t max_salt_len = 8;
 	char *method = "DES";
 
 	result[0] = '\0';
@@ -170,20 +172,20 @@ char *crypt_make_salt (char *meth, void *arg)
 		if (getdef_bool ("MD5_CRYPT_ENAB"))
 			method = "MD5";
 
-	if (!strncmp (method, "MD5", 3)) {
+	if (!strcmp (method, "MD5")) {
 		MAGNUM(result, '1');
 		max_salt_len = 11;
 #ifdef ENCRYPTMETHOD_SELECT
-	} else if (!strncmp (method, "SHA256", 6)) {
+	} else if (!strcmp (method, "SHA256")) {
 		MAGNUM(result, '5');
 		strcat(result, SHA_salt_rounds((int *)arg));
 		max_salt_len = strlen(result) + SHA_salt_size();
-	} else if (!strncmp (method, "SHA512", 6)) {
+	} else if (!strcmp (method, "SHA512")) {
 		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)) {
+	} else if (0 != strcmp (method, "DES")) {
 		fprintf (stderr,
 			 _("Invalid ENCRYPT_METHOD value: '%s'.\n"
 			   "Defaulting to DES.\n"),
diff --git a/src/chgpasswd.c b/src/chgpasswd.c
index 9a37565c..2eabb2b7 100644
--- a/src/chgpasswd.c
+++ b/src/chgpasswd.c
@@ -185,7 +185,7 @@ int main (int argc, char **argv)
 		usage ();
 	}
 	if ((eflg && (md5flg || cflg)) ||
-	    md5flg && cflg) {
+	    (md5flg && cflg)) {
 		fprintf (stderr,
 			 _("%s: the -c, -e, and -m flags are exclusive\n"),
 			 Prog);
diff --git a/src/chpasswd.c b/src/chpasswd.c
index dd8f1a96..73e76759 100644
--- a/src/chpasswd.c
+++ b/src/chpasswd.c
@@ -179,7 +179,7 @@ int main (int argc, char **argv)
 		usage ();
 	}
 	if ((eflg && (md5flg || cflg)) ||
-	    md5flg && cflg) {
+	    (md5flg && cflg)) {
 		fprintf (stderr,
 			 _("%s: the -c, -e, and -m flags are exclusive\n"),
 			 Prog);
diff --git a/src/gpasswd.c b/src/gpasswd.c
index 67a656ee..861dca08 100644
--- a/src/gpasswd.c
+++ b/src/gpasswd.c
@@ -121,7 +121,7 @@ static int check_list (const char *users)
 	const char *start, *end;
 	char username[32];
 	int errors = 0;
-	int len;
+	size_t len;
 
 	for (start = users; start && *start; start = end) {
 		if ((end = strchr (start, ','))) {
diff --git a/src/passwd.c b/src/passwd.c
index 592fc4a3..282ffef1 100644
--- a/src/passwd.c
+++ b/src/passwd.c
@@ -251,9 +251,9 @@ static int new_password (const struct passwd *pw)
 			pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
 #ifdef ENCRYPTMETHOD_SELECT
 	} else {
-		if (!strncmp (method, "MD5"   , 3) ||
-		    !strncmp (method, "SHA256", 6) ||
-		    !strncmp (method, "SHA512", 6))
+		if (!strcmp (method, "MD5") ||
+		    !strcmp (method, "SHA256") ||
+		    !strcmp (method, "SHA512"))
 			pass_max_len = -1;
 		else
 			pass_max_len = getdef_num ("PASS_MAX_LEN", 8);