Since r7266, it's been possible to get a hostname into Default Settings; but
[u/mdw/putty] / unix / uxnoise.c
... / ...
CommitLineData
1/*
2 * Noise generation for PuTTY's cryptographic random number
3 * generator.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <errno.h>
9
10#include <fcntl.h>
11#include <unistd.h>
12#include <sys/time.h>
13#include <sys/resource.h>
14
15#include "putty.h"
16#include "ssh.h"
17#include "storage.h"
18
19static int read_dev_urandom(char *buf, int len)
20{
21 int fd;
22 int ngot, ret;
23
24 fd = open("/dev/urandom", O_RDONLY);
25 if (fd < 0)
26 return 0;
27
28 ngot = 0;
29 while (ngot < len) {
30 ret = read(fd, buf+ngot, len-ngot);
31 if (ret < 0) {
32 close(fd);
33 return 0;
34 }
35 ngot += ret;
36 }
37
38 return 1;
39}
40
41/*
42 * This function is called once, at PuTTY startup. It will do some
43 * slightly silly things such as fetching an entire process listing
44 * and scanning /tmp, load the saved random seed from disk, and
45 * also read 32 bytes out of /dev/urandom.
46 */
47
48void noise_get_heavy(void (*func) (void *, int))
49{
50 char buf[512];
51 FILE *fp;
52 int ret;
53 int got_dev_urandom = 0;
54
55 if (read_dev_urandom(buf, 32)) {
56 got_dev_urandom = 1;
57 func(buf, 32);
58 }
59
60 fp = popen("ps -axu 2>/dev/null", "r");
61 if (fp) {
62 while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
63 func(buf, ret);
64 pclose(fp);
65 } else if (!got_dev_urandom) {
66 fprintf(stderr, "popen: %s\n"
67 "Unable to access fallback entropy source\n", strerror(errno));
68 exit(1);
69 }
70
71 fp = popen("ls -al /tmp 2>/dev/null", "r");
72 if (fp) {
73 while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
74 func(buf, ret);
75 pclose(fp);
76 } else if (!got_dev_urandom) {
77 fprintf(stderr, "popen: %s\n"
78 "Unable to access fallback entropy source\n", strerror(errno));
79 exit(1);
80 }
81
82 read_random_seed(func);
83 random_save_seed();
84}
85
86void random_save_seed(void)
87{
88 int len;
89 void *data;
90
91 if (random_active) {
92 random_get_savedata(&data, &len);
93 write_random_seed(data, len);
94 sfree(data);
95 }
96}
97
98/*
99 * This function is called every time the random pool needs
100 * stirring, and will acquire the system time.
101 */
102void noise_get_light(void (*func) (void *, int))
103{
104 struct timeval tv;
105 gettimeofday(&tv, NULL);
106 func(&tv, sizeof(tv));
107}
108
109/*
110 * This function is called on a timer, and grabs as much changeable
111 * system data as it can quickly get its hands on.
112 */
113void noise_regular(void)
114{
115 int fd;
116 int ret;
117 char buf[512];
118 struct rusage rusage;
119
120 if ((fd = open("/proc/meminfo", O_RDONLY)) >= 0) {
121 while ( (ret = read(fd, buf, sizeof(buf))) > 0)
122 random_add_noise(buf, ret);
123 close(fd);
124 }
125 if ((fd = open("/proc/stat", O_RDONLY)) >= 0) {
126 while ( (ret = read(fd, buf, sizeof(buf))) > 0)
127 random_add_noise(buf, ret);
128 close(fd);
129 }
130 getrusage(RUSAGE_SELF, &rusage);
131 random_add_noise(&rusage, sizeof(rusage));
132}
133
134/*
135 * This function is called on every keypress or mouse move, and
136 * will add the current time to the noise pool. It gets the scan
137 * code or mouse position passed in, and adds that too.
138 */
139void noise_ultralight(unsigned long data)
140{
141 struct timeval tv;
142 gettimeofday(&tv, NULL);
143 random_add_noise(&tv, sizeof(tv));
144 random_add_noise(&data, sizeof(data));
145}