1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-26 01:32:25 +00:00

Improve the noise collection for the internal random pool.

[originally from svn r2182]
This commit is contained in:
Simon Tatham 2002-11-02 15:23:20 +00:00
parent 93e9fadc75
commit 53eb272766
4 changed files with 98 additions and 29 deletions

View File

@ -25,6 +25,10 @@ void cleanup_exit(int code)
* Clean up. * Clean up.
*/ */
sk_cleanup(); sk_cleanup();
if (cfg.protocol == PROT_SSH)
random_save_seed();
exit(code); exit(code);
} }

View File

@ -7,58 +7,76 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h>
#include "putty.h" #include "putty.h"
#include "ssh.h" #include "ssh.h"
#include "storage.h" #include "storage.h"
/* static int read_dev_urandom(char *buf, int len)
* FIXME. This module currently depends critically on /dev/urandom,
* because it has no fallback mechanism for doing anything else.
*/
static void read_dev_urandom(char *buf, int len)
{ {
int fd; int fd;
int ngot, ret; int ngot, ret;
fd = open("/dev/urandom", O_RDONLY); fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) { if (fd < 0)
perror("/dev/urandom: open"); return 0;
exit(1);
}
ngot = 0; ngot = 0;
while (ngot < len) { while (ngot < len) {
ret = read(fd, buf+ngot, len-ngot); ret = read(fd, buf+ngot, len-ngot);
if (ret < 0) { if (ret < 0) {
perror("/dev/urandom: read"); close(fd);
exit(1); return 0;
} }
ngot += ret; ngot += ret;
} }
return 1;
} }
/* /*
* This function is called once, at PuTTY startup. Currently it * This function is called once, at PuTTY startup. It will do some
* will read 32 bytes out of /dev/urandom and seed the internal * slightly silly things such as fetching an entire process listing
* generator with them. * and scanning /tmp, load the saved random seed from disk, and
* also read 32 bytes out of /dev/urandom.
*/ */
void noise_get_heavy(void (*func) (void *, int)) void noise_get_heavy(void (*func) (void *, int))
{ {
char buf[32]; char buf[512];
read_dev_urandom(buf, sizeof(buf)); FILE *fp;
func(buf, sizeof(buf)); int ret;
if (read_dev_urandom(buf, 32))
func(buf, 32);
fp = popen("ps -axu 2>/dev/null", "r");
while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
func(buf, ret);
pclose(fp);
fp = popen("ls -al /tmp 2>/dev/null", "r");
while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
func(buf, ret);
pclose(fp);
read_random_seed(func);
} }
void random_save_seed(void) void random_save_seed(void)
{ {
/* Currently we do nothing here. FIXME? */ int len;
void *data;
if (random_active) {
random_get_savedata(&data, &len);
write_random_seed(data, len);
}
} }
/* /*
* This function is called every time the urandom pool needs * This function is called every time the random pool needs
* stirring, and will acquire the system time. * stirring, and will acquire the system time.
*/ */
void noise_get_light(void (*func) (void *, int)) void noise_get_light(void (*func) (void *, int))
@ -69,16 +87,28 @@ void noise_get_light(void (*func) (void *, int))
} }
/* /*
* This function is called on a timer, and it will just pull some * This function is called on a timer, and grabs as much changeable
* stuff out of /dev/urandom. FIXME: really I suspect we ought not * system data as it can quickly get its hands on.
* to deplete /dev/urandom like this. Better to grab something more
* harmless.
*/ */
void noise_regular(void) void noise_regular(void)
{ {
char buf[4]; int fd;
read_dev_urandom(buf, sizeof(buf)); int ret;
random_add_noise(buf, sizeof(buf)); char buf[512];
struct rusage rusage;
if ((fd = open("/proc/meminfo", O_RDONLY)) >= 0) {
while ( (ret = read(fd, buf, sizeof(buf))) > 0)
random_add_noise(buf, ret);
close(fd);
}
if ((fd = open("/proc/stat", O_RDONLY)) >= 0) {
while ( (ret = read(fd, buf, sizeof(buf))) > 0)
random_add_noise(buf, ret);
close(fd);
}
getrusage(RUSAGE_SELF, &rusage);
random_add_noise(&rusage, sizeof(rusage));
} }
/* /*

View File

@ -584,5 +584,6 @@ int main(int argc, char **argv)
fprintf(stderr, "Remote process exit code unavailable\n"); fprintf(stderr, "Remote process exit code unavailable\n");
exitcode = 1; /* this is an error condition */ exitcode = 1; /* this is an error condition */
} }
return exitcode; cleanup_exit(exitcode);
return exitcode; /* shouldn't happen, but placates gcc */
} }

View File

@ -156,7 +156,7 @@ void enum_settings_finish(void *handle)
} }
enum { enum {
INDEX_DIR, INDEX_HOSTKEYS INDEX_DIR, INDEX_HOSTKEYS, INDEX_RANDSEED
}; };
static void make_filename(char *filename, int index) static void make_filename(char *filename, int index)
@ -169,6 +169,7 @@ static void make_filename(char *filename, int index)
strncpy(filename + len, strncpy(filename + len,
index == INDEX_DIR ? "/.putty" : index == INDEX_DIR ? "/.putty" :
index == INDEX_HOSTKEYS ? "/.putty/sshhostkeys" : index == INDEX_HOSTKEYS ? "/.putty/sshhostkeys" :
index == INDEX_RANDSEED ? "/.putty/randomseed" :
"/.putty/ERROR", FILENAME_MAX - len); "/.putty/ERROR", FILENAME_MAX - len);
filename[FILENAME_MAX-1] = '\0'; filename[FILENAME_MAX-1] = '\0';
} }
@ -297,10 +298,43 @@ void store_host_key(char *hostname, int port, char *keytype, char *key)
void read_random_seed(noise_consumer_t consumer) void read_random_seed(noise_consumer_t consumer)
{ {
int fd;
char fname[FILENAME_MAX];
make_filename(fname, INDEX_RANDSEED);
fd = open(fname, O_RDONLY);
if (fd) {
char buf[512];
int ret;
while ( (ret = read(fd, buf, sizeof(buf))) > 0)
consumer(buf, ret);
close(fd);
}
} }
void write_random_seed(void *data, int len) void write_random_seed(void *data, int len)
{ {
int fd;
char fname[FILENAME_MAX];
make_filename(fname, INDEX_RANDSEED);
fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (fd < 0) {
char dir[FILENAME_MAX];
make_filename(dir, INDEX_DIR);
mkdir(dir, 0700);
fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0600);
}
while (len > 0) {
int ret = write(fd, data, len);
if (ret <= 0) break;
len -= ret;
data = (char *)data + len;
}
close(fd);
} }
void cleanup_all(void) void cleanup_all(void)