passwd: Use a random salt when encrypting passwords - ubase - suckless linux ba… | |
git clone git://git.suckless.org/ubase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit fae9ca81a2eaf3534299b7ca3033b1e6605f9ab2 | |
parent 3a5939e81018a05d710d0f3c8cea8794dd8a1637 | |
Author: Michael Forney <[email protected]> | |
Date: Sun, 23 Oct 2016 20:59:51 -0700 | |
passwd: Use a random salt when encrypting passwords | |
Diffstat: | |
M passwd.c | 39 ++++++++++++++++++++++++++---… | |
1 file changed, 33 insertions(+), 6 deletions(-) | |
--- | |
diff --git a/passwd.c b/passwd.c | |
@@ -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> | |
@@ -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[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcde… | |
+ 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) | |
{ | |
@@ -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_… | |
struct passwd *pw; | |
struct spwd *spw = NULL; | |
FILE *fp = NULL; | |
@@ -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); | |
@@ -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); | |
@@ -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); |