summaryrefslogblamecommitdiffstats
path: root/patches/source/shadow/shadow.glibc217-crypt.diff
blob: e26ca10bbb770026ed36c88798dc911cad9569f0 (plain) (tree)

































































































































































































































































                                                                                         
From a616a72160c17fa193ad6ad95eb2c869633f4fe9 Mon Sep 17 00:00:00 2001
From: mancha <mancha1@hush.com>
Date: Fri, 4 Oct 2013 11:25:43
Subject: [PATCH] Improve handling of NULL returns from crypt().

Signed-off-by: mancha <mancha1@hush.com>
---
 ChangeLog       |   15 +++++++++++++++
 lib/encrypt.c   |    7 +++----
 lib/pwauth.c    |    7 ++++++-
 libmisc/valid.c |    1 +
 src/chgpasswd.c |    4 ++++
 src/chpasswd.c  |    4 ++++
 src/gpasswd.c   |    4 ++++
 src/newgrp.c    |    3 ++-
 src/newusers.c  |   26 +++++++++++++++++++++-----
 src/passwd.c    |   15 +++++++++++++++
 10 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index aab00ae..1416a38 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2013-05-06  mancha            <mancha1@hush.com>
+
+        * lib/encrypt.c: crypt() in glibc/eglibc 2.17 now fails if passed
+          a salt that violates specs. On Linux, crypt() also fails with
+          DES/MD5 salts in FIPS140 mode. Rather than exit() on NULL returns
+          we send them back to the caller for appropriate handling.
+        * lib/pwauth.c: Handle NULL return from crypt().
+        * libmisc/valid.c: Likewise.
+        * src/chgpasswd.c: Likewise.
+        * src/chpasswd.c: Likewise.
+        * src/gpasswd.c: Likewise.
+        * src/newgrp.c: Likewise.
+        * src/newusers.c: Likewise.
+        * src/passwd.c: Likewise.
+
 2012-05-25  Nicolas François  <nicolas.francois@centraliens.net>
 
 	* NEWS: Set release date.
diff --git a/lib/encrypt.c b/lib/encrypt.c
index 7daa8da..49cb691 100644
--- a/lib/encrypt.c
+++ b/lib/encrypt.c
@@ -49,11 +49,10 @@
 	if (!cp) {
 		/*
 		 * Single Unix Spec: crypt() may return a null pointer,
-		 * and set errno to indicate an error.  The caller doesn't
-		 * expect us to return NULL, so...
+		 * and set errno to indicate an error. In this case return
+		 * the NULL so the caller can handle appropriately.
 		 */
-		perror ("crypt");
-		exit (EXIT_FAILURE);
+		return cp;
 	}
 
 	/* The GNU crypt does not return NULL if the algorithm is not
diff --git a/lib/pwauth.c b/lib/pwauth.c
index 4b26daa..086a72e 100644
--- a/lib/pwauth.c
+++ b/lib/pwauth.c
@@ -73,6 +73,7 @@ int pw_auth (const char *cipher,
 	char prompt[1024];
 	char *clear = NULL;
 	const char *cp;
+	const char *encrypted;
 	int retval;
 
 #ifdef	SKEY
@@ -177,7 +178,11 @@ int pw_auth (const char *cipher,
 	 * the results there as well.
 	 */
 
-	retval = strcmp (pw_encrypt (input, cipher), cipher);
+	encrypted = pw_encrypt (input, cipher);
+	if (encrypted!=NULL)
+		retval = strcmp (encrypted, cipher);
+	else
+		retval = -1;
 
 #ifdef  SKEY
 	/*
diff --git a/libmisc/valid.c b/libmisc/valid.c
index aa0390a..4b85d67 100644
--- a/libmisc/valid.c
+++ b/libmisc/valid.c
@@ -95,6 +95,7 @@ bool valid (const char *password, const struct passwd *ent)
 	 */
 
 	if (   (NULL != ent->pw_name)
+	    && (NULL != encrypted)
 	    && (strcmp (encrypted, ent->pw_passwd) == 0)) {
 		return true;
 	} else {
diff --git a/src/chgpasswd.c b/src/chgpasswd.c
index 0f41d0b..6c42a09 100644
--- a/src/chgpasswd.c
+++ b/src/chgpasswd.c
@@ -469,6 +469,10 @@ int main (int argc, char **argv)
 #endif
 			cp = pw_encrypt (newpwd,
 			                 crypt_make_salt (crypt_method, arg));
+			if (cp == NULL) {
+				perror ("crypt");
+				exit (EXIT_FAILURE);
+			}	
 		}
 
 		/*
diff --git a/src/chpasswd.c b/src/chpasswd.c
index 928e2d7..4968b0d 100644
--- a/src/chpasswd.c
+++ b/src/chpasswd.c
@@ -492,6 +492,10 @@ int main (int argc, char **argv)
 #endif
 			cp = pw_encrypt (newpwd,
 			                 crypt_make_salt(crypt_method, arg));
+			if (cp == NULL) {
+				perror ("crypt");
+				exit (EXIT_FAILURE);
+			}
 		}
 
 		/*
diff --git a/src/gpasswd.c b/src/gpasswd.c
index df8d714..0043610 100644
--- a/src/gpasswd.c
+++ b/src/gpasswd.c
@@ -939,6 +939,10 @@ static void change_passwd (struct group *gr)
 	}
 
 	cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL));
+	if (cp==NULL) {
+		perror ("crypt");
+		exit (EXIT_FAILURE);
+	}
 	memzero (pass, sizeof pass);
 #ifdef SHADOWGRP
 	if (is_shadowgrp) {
diff --git a/src/newgrp.c b/src/newgrp.c
index 9330c72..6b87761 100644
--- a/src/newgrp.c
+++ b/src/newgrp.c
@@ -184,7 +184,8 @@ static void check_perms (const struct group *grp,
 		cpasswd = pw_encrypt (cp, grp->gr_passwd);
 		strzero (cp);
 
-		if (grp->gr_passwd[0] == '\0' ||
+		if (cpasswd == NULL ||
+		    grp->gr_passwd[0] == '\0' ||
 		    strcmp (cpasswd, grp->gr_passwd) != 0) {
 #ifdef WITH_AUDIT
 			snprintf (audit_buf, sizeof(audit_buf),
diff --git a/src/newusers.c b/src/newusers.c
index 994898e..5f83a6a 100644
--- a/src/newusers.c
+++ b/src/newusers.c
@@ -387,6 +387,7 @@ static int add_user (const char *name, uid_t uid, gid_t gid)
 static void update_passwd (struct passwd *pwd, const char *password)
 {
 	void *crypt_arg = NULL;
+	char *cp;
 	if (crypt_method != NULL) {
 #ifdef USE_SHA_CRYPT
 		if (sflg) {
@@ -398,9 +399,13 @@ static void update_passwd (struct passwd *pwd, const char *password)
 	if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) {
 		pwd->pw_passwd = (char *)password;
 	} else {
-		pwd->pw_passwd = pw_encrypt (password,
-		                             crypt_make_salt (crypt_method,
-		                                              crypt_arg));
+		cp=pw_encrypt (password, crypt_make_salt (crypt_method, 
+		                                          crypt_arg));
+		if (cp == NULL) {
+			perror ("crypt");
+			exit (EXIT_FAILURE);
+		}
+		pwd->pw_passwd = cp;
 	}
 }
 #endif				/* !USE_PAM */
@@ -412,6 +417,7 @@ static int add_passwd (struct passwd *pwd, const char *password)
 {
 	const struct spwd *sp;
 	struct spwd spent;
+	char *cp;
 
 #ifndef USE_PAM
 	void *crypt_arg = NULL;
@@ -448,7 +454,12 @@ static int add_passwd (struct passwd *pwd, const char *password)
 		} else {
 			const char *salt = crypt_make_salt (crypt_method,
 			                                    crypt_arg);
-			spent.sp_pwdp = pw_encrypt (password, salt);
+			cp = pw_encrypt (password, salt);
+			if (cp == NULL) {
+				perror ("crypt");
+				exit (EXIT_FAILURE);
+			}
+			spent.sp_pwdp = cp;
 		}
 		spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
 		if (0 == spent.sp_lstchg) {
@@ -492,7 +503,12 @@ static int add_passwd (struct passwd *pwd, const char *password)
 		spent.sp_pwdp = (char *)password;
 	} else {
 		const char *salt = crypt_make_salt (crypt_method, crypt_arg);
-		spent.sp_pwdp = pw_encrypt (password, salt);
+		cp = pw_encrypt (password, salt);
+		if (cp == NULL) {
+			perror ("crypt");
+			exit (EXIT_FAILURE);
+		}
+		spent.sp_pwdp = cp;
 	}
 #else
 	/*
diff --git a/src/passwd.c b/src/passwd.c
index ac90aa3..ae26666 100644
--- a/src/passwd.c
+++ b/src/passwd.c
@@ -242,6 +242,17 @@ static int new_password (const struct pa
 		}
 
 		cipher = pw_encrypt (clear, crypt_passwd);
+		if (cipher == NULL) {
+			strzero (clear);
+			(void) fprintf (stderr,
+			                _("Failed to crypt password for %s.\n"),
+			                pw->pw_name);
+			SYSLOG ((LOG_INFO,
+			 	 "failed to crypt password for %s",
+			 	 pw->pw_name));
+			return -1;
+		}
+		
 		if (strcmp (cipher, crypt_passwd) != 0) {
 			strzero (clear);
 			strzero (cipher);
@@ -349,6 +360,10 @@ static int new_password (const struct pa
 	 * Encrypt the password, then wipe the cleartext password.
 	 */
 	cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL));
+	if (cp == NULL) {
+		perror ("crypt");
+		exit (EXIT_FAILURE);
+	}
 	memzero (pass, sizeof pass);
 
 #ifdef HAVE_LIBCRACK_HIST
-- 
1.7.11.4