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:
parent
93e9fadc75
commit
53eb272766
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user