summaryrefslogtreecommitdiff
path: root/source3/lib/genrand.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1998-04-21 07:17:35 +0000
committerAndrew Tridgell <tridge@samba.org>1998-04-21 07:17:35 +0000
commita63bcb436ad41058e6425c84c1a9994036be1166 (patch)
tree62fc88abd4b05035dd4028ba2946de26ea38bf0e /source3/lib/genrand.c
parent76d3bc36a5ce13d2a7bd08f9c18b2cfd0ab0210f (diff)
downloadsamba-a63bcb436ad41058e6425c84c1a9994036be1166.tar.gz
samba-a63bcb436ad41058e6425c84c1a9994036be1166.tar.bz2
samba-a63bcb436ad41058e6425c84c1a9994036be1166.zip
improved the secret buffer generation a bit. It now uses /etc/shadow
and smbpasswd if possible, and doesn't put it all through a 32 bit bottleneck. (This used to be commit 356ec24840da98f9e0b49b8eecb56aeec5ed848e)
Diffstat (limited to 'source3/lib/genrand.c')
-rw-r--r--source3/lib/genrand.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/source3/lib/genrand.c b/source3/lib/genrand.c
index 5808206f6b..78d19da00a 100644
--- a/source3/lib/genrand.c
+++ b/source3/lib/genrand.c
@@ -26,6 +26,30 @@
extern int DEBUGLEVEL;
static uint32 counter = 0;
+
+/****************************************************************
+get a 16 byte hash from the contents of a file
+Note that the hash is not initialised.
+*****************************************************************/
+static void do_filehash(char *fname, unsigned char *hash)
+{
+ unsigned char buf[1011]; /* deliberate weird size */
+ unsigned char tmp_md4[16];
+ int fd, n;
+
+ fd = open(fname,O_RDONLY);
+ if (fd == -1) return;
+
+ while ((n = read(fd, (char *)buf, sizeof(buf))) > 0) {
+ mdfour(tmp_md4, buf, n);
+ for (n=0;n<16;n++)
+ hash[n] ^= tmp_md4[n];
+ }
+ close(fd);
+}
+
+
+
/****************************************************************
Try and get a seed by looking at the atimes of files in a given
directory. XOR them into the buf array.
@@ -81,14 +105,15 @@ static void do_dirrand(char *name, unsigned char *buf, int buf_len)
XOR all the file timestamps. If this fails then just use
a combination of pid and time of day (yes I know this
sucks :-). Finally md4 the result.
+
+ The result goes in a 16 byte buffer passed from the caller
**************************************************************/
-static uint32 do_reseed(void)
+static void do_reseed(unsigned char *md4_outbuf)
{
- unsigned char md4_outbuf[16];
unsigned char md4_inbuf[40];
BOOL got_random = False;
- uint32 v1, v2, ret;
+ uint32 v1, v2;
int fd;
struct timeval tval;
pid_t mypid;
@@ -115,6 +140,10 @@ static uint32 do_reseed(void)
do_dirrand("/dev", md4_inbuf, sizeof(md4_inbuf));
}
+ /* possibly add in some secret file contents */
+ do_filehash("/etc/shadow", &md4_inbuf[0]);
+ do_filehash(SMB_PASSWD_FILE, &md4_inbuf[16]);
+
/*
* Finally add the counter, time of day, and pid.
*/
@@ -124,19 +153,9 @@ static uint32 do_reseed(void)
v2 = (counter++) * mypid + tval.tv_usec;
SIVAL(md4_inbuf, 32, v1 ^ IVAL(md4_inbuf, 32));
- SIVAL(md4_inbuf, 36, v1 ^ IVAL(md4_inbuf, 36));
+ SIVAL(md4_inbuf, 36, v2 ^ IVAL(md4_inbuf, 36));
mdfour(md4_outbuf, md4_inbuf, sizeof(md4_inbuf));
-
- /* XOR everything togther in blocks of 4 bytes. */
- ret = IVAL(md4_outbuf,0);
- ret ^= IVAL(md4_outbuf,4);
- ret ^= IVAL(md4_outbuf,8);
- ret ^= IVAL(md4_outbuf,12);
-
- DEBUG(10,("do_reseed: returning seed %lu\n", ret));
-
- return ret;
}
/*******************************************************************
@@ -146,13 +165,13 @@ static uint32 do_reseed(void)
void generate_random_buffer( unsigned char *out, int len, BOOL re_seed)
{
static BOOL done_reseed = False;
- unsigned char tmp_buf[64];
+ unsigned char tmp_buf[16];
unsigned char md4_buf[16];
unsigned char *p;
if(!done_reseed || re_seed) {
- srandom(do_reseed());
- done_reseed = True;
+ do_reseed(md4_buf);
+ done_reseed = True;
}
/*
@@ -162,12 +181,10 @@ void generate_random_buffer( unsigned char *out, int len, BOOL re_seed)
p = out;
while(len > 0) {
- int i;
int copy_len = len > 16 ? 16 : len;
- for( i = 0; i < 16; i++)
- SIVAL(tmp_buf, i*4, random());
- mdfour(md4_buf, tmp_buf, sizeof(tmp_buf));
- memcpy(p, md4_buf, copy_len);
+ mdfour(tmp_buf, md4_buf, sizeof(md4_buf));
+ memcpy(md4_buf, tmp_buf, sizeof(md4_buf));
+ memcpy(p, tmp_buf, copy_len);
p += copy_len;
len -= copy_len;
}