summaryrefslogtreecommitdiffstats
path: root/pw
diff options
context:
space:
mode:
authorDavid Nugent <davidn@FreeBSD.org>1996-12-16 17:37:58 +0000
committerDavid Nugent <davidn@FreeBSD.org>1996-12-16 17:37:58 +0000
commit8e2576489faf8bc850d815512bcc9f185e565604 (patch)
tree37c68a0d1e848cf8b0f9f948767f0a83c51c8f04 /pw
parentbff8585150d3998c4658637ddc661e86609cee53 (diff)
downloadpw-darwin-8e2576489faf8bc850d815512bcc9f185e565604.tar.gz
pw-darwin-8e2576489faf8bc850d815512bcc9f185e565604.tar.zst
pw-darwin-8e2576489faf8bc850d815512bcc9f185e565604.zip
Reviewed by: davidn@blaze.net.au
Submitted by: proff@iq.org Security patch for better random password generation.
Diffstat (limited to 'pw')
-rw-r--r--pw/pw_user.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/pw/pw_user.c b/pw/pw_user.c
index 055f676..150c71c 100644
--- a/pw/pw_user.c
+++ b/pw/pw_user.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pw_user.c,v 1.1.1.3 1996/12/10 23:59:02 joerg Exp $
+ * $Id: pw_user.c,v 1.2 1996/12/11 15:10:47 joerg Exp $
*/
#include <unistd.h>
@@ -33,6 +33,10 @@
#include <sys/param.h>
#include <dirent.h>
#include <termios.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <md5.h>
#include "pw.h"
#include "bitmap.h"
#include "pwupd.h"
@@ -730,7 +734,7 @@ pw_pwcrypt(char *password)
/*
* Calculate a salt value
*/
- srandom((unsigned) (time(NULL) | getpid()));
+ srandom((unsigned) (time(NULL) ^ getpid()));
for (i = 0; i < 8; i++)
salt[i] = chars[random() % 63];
salt[i] = '\0';
@@ -738,19 +742,61 @@ pw_pwcrypt(char *password)
return strcpy(buf, crypt(password, salt));
}
+u_char *
+pw_genmd5rand (u_char *d) /* cryptographically secure rng */
+{
+ MD5_CTX md5_ctx;
+ struct timeval tv, tvo;
+ struct rusage ru;
+ int n=0;
+ int t;
+ MD5Init (&md5_ctx);
+ t=getpid();
+ MD5Update (&md5_ctx, (u_char*)&t, sizeof t);
+ t=getppid();
+ MD5Update (&md5_ctx, (u_char*)&t, sizeof t);
+ gettimeofday (&tvo, NULL);
+ do {
+ getrusage (RUSAGE_SELF, &ru);
+ MD5Update (&md5_ctx, (u_char*)&ru, sizeof ru);
+ gettimeofday (&tv, NULL);
+ MD5Update (&md5_ctx, (u_char*)&tv, sizeof tv);
+ } while (n++<20 || tv.tv_usec-tvo.tv_usec<100*1000);
+ MD5Final (d, &md5_ctx);
+ return d;
+}
+
+static u_char *
+pw_getrand(u_char *buf, int len)
+{
+ int fd;
+ fd = open("/dev/urandom", O_RDONLY);
+ if (!fd || read(fd, buf, len)!=len) {
+ int n;
+ for (n=0;n<len;n+=16) {
+ u_char ubuf[16];
+ pw_genmd5rand(ubuf);
+ memcpy(buf+n, ubuf, MIN(16, len-n));
+ }
+ }
+ close(fd);
+ return buf;
+}
static char *
pw_password(struct userconf * cnf, struct cargs * args, char const * user)
{
int i, l;
char pwbuf[32];
+ u_char rndbuf[sizeof pwbuf];
switch (cnf->default_password) {
case -1: /* Random password */
- srandom((unsigned) (time(NULL) | getpid()));
+ srandom((unsigned) (time(NULL) ^ getpid()));
l = (random() % 8 + 8); /* 8 - 16 chars */
+ pw_getrand(rndbuf, l);
for (i = 0; i < l; i++)
- pwbuf[i] = chars[random() % sizeof(chars)];
+ pwbuf[i] = chars[rndbuf[i] % sizeof(chars)];
pwbuf[i] = '\0';
/*