[hackers] [ubase] [PATCH] passwd: Use a random salt when encrypting passwords

From: Michael Forney <mforney_AT_mforney.org>
Date: Sun, 23 Oct 2016 20:59:51 -0700

---
 passwd.c | 39 +++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/passwd.c b/passwd.c
index 3ea3dd1..52b70a8 100644
--- a/passwd.c
+++ b/passwd.c
_AT_@ -2,12 +2,14 @@
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/syscall.h>
 
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <pwd.h>
 #include <shadow.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
_AT_@ -127,6 +129,27 @@ cleanup:
 	return r;
 }
 
+/* generates a random base64-encoded salt string of length 16 */
+static void
+gensalt(char *s)
+{
+	static const char b64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+	uint8_t buf[12];
+	uint32_t n;
+	int i;
+
+	if (syscall(SYS_getrandom, buf, sizeof(buf), 0) < 0)
+		eprintf("getrandom:");
+	for (i = 0; i < 12; i += 3) {
+		n = buf[i] << 16 | buf[i+1] << 8 | buf[i+2];
+		*s++ = b64[n%64]; n /= 64;
+		*s++ = b64[n%64]; n /= 64;
+		*s++ = b64[n%64]; n /= 64;
+		*s++ = b64[n];
+	}
+	*s++ = '\0';
+}
+
 static void
 usage(void)
 {
_AT_@ -137,7 +160,7 @@ int
 main(int argc, char *argv[])
 {
 	char *cryptpass1 = NULL, *cryptpass2 = NULL, *cryptpass3 = NULL;
-	char *inpass, *p, *salt = PW_CIPHER, *prevhash = NULL;
+	char *inpass, *p, *prevhash = NULL, salt[sizeof(PW_CIPHER) + 16] = PW_CIPHER;
 	struct passwd *pw;
 	struct spwd *spw = NULL;
 	FILE *fp = NULL;
_AT_@ -188,9 +211,9 @@ main(int argc, char *argv[])
 			goto newpass;
 		}
 		if (pw->pw_passwd[0] == 'x')
-			prevhash = salt = spw->sp_pwdp;
+			prevhash = spw->sp_pwdp;
 		else
-			prevhash = salt = pw->pw_passwd;
+			prevhash = pw->pw_passwd;
 	}
 
 	printf("Changing password for %s\n", pw->pw_name);
_AT_@ -199,7 +222,7 @@ main(int argc, char *argv[])
 		eprintf("getpass:");
 	if (inpass[0] == '\0')
 		eprintf("no password supplied\n");
-	p = crypt(inpass, salt);
+	p = crypt(inpass, prevhash);
 	if (!p)
 		eprintf("crypt:");
 	cryptpass1 = estrdup(p);
_AT_@ -212,12 +235,16 @@ newpass:
 		eprintf("getpass:");
 	if (inpass[0] == '\0')
 		eprintf("no password supplied\n");
+	p = crypt(inpass, prevhash);
+	if (!p)
+		eprintf("crypt:");
+	if (cryptpass1 && strcmp(cryptpass1, p) == 0)
+		eprintf("password left unchanged\n");
+	gensalt(salt + strlen(salt));
 	p = crypt(inpass, salt);
 	if (!p)
 		eprintf("crypt:");
 	cryptpass2 = estrdup(p);
-	if (cryptpass1 && strcmp(cryptpass1, cryptpass2) == 0)
-		eprintf("password left unchanged\n");
 
 	/* Flush pending input */
 	ioctl(0, TCFLSH, (void *)0);
-- 
2.10.1
Received on Mon Oct 24 2016 - 05:59:51 CEST

This archive was generated by hypermail 2.3.0 : Mon Oct 24 2016 - 06:12:14 CEST