annotate src/lib/randgen.c @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents 2e2563132d5f
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 19552
diff changeset
1 /* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "randgen.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5
3040
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
6
9204
1849c4269ad8 If /dev/arandom exists (OpenBSD), use it instead of /dev/urandom.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
7 #ifdef DEV_URANDOM_PATH
7436
cdb007c1923d random_fill(): If read(/dev/urandom) returned EINTR, it could have written
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
8
1335
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
9 #include "fd-close-on-exec.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include <unistd.h>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include <fcntl.h>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 static int init_refcount = 0;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 static int urandom_fd;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15
183
4a7ab9e94f25 size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents: 62
diff changeset
16 void random_fill(void *buf, size_t size)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 {
183
4a7ab9e94f25 size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents: 62
diff changeset
18 size_t pos;
4a7ab9e94f25 size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents: 62
diff changeset
19 ssize_t ret;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 i_assert(init_refcount > 0);
183
4a7ab9e94f25 size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents: 62
diff changeset
22 i_assert(size < SSIZE_T_MAX);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23
7436
cdb007c1923d random_fill(): If read(/dev/urandom) returned EINTR, it could have written
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
24 for (pos = 0; pos < size; ) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 ret = read(urandom_fd, (char *) buf + pos, size - pos);
7436
cdb007c1923d random_fill(): If read(/dev/urandom) returned EINTR, it could have written
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
26 if (unlikely(ret <= 0)) {
cdb007c1923d random_fill(): If read(/dev/urandom) returned EINTR, it could have written
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
27 if (ret == 0)
9204
1849c4269ad8 If /dev/arandom exists (OpenBSD), use it instead of /dev/urandom.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
28 i_fatal("EOF when reading from "DEV_URANDOM_PATH);
7436
cdb007c1923d random_fill(): If read(/dev/urandom) returned EINTR, it could have written
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
29 else if (errno != EINTR)
9204
1849c4269ad8 If /dev/arandom exists (OpenBSD), use it instead of /dev/urandom.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
30 i_fatal("read("DEV_URANDOM_PATH") failed: %m");
7436
cdb007c1923d random_fill(): If read(/dev/urandom) returned EINTR, it could have written
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
31 } else {
cdb007c1923d random_fill(): If read(/dev/urandom) returned EINTR, it could have written
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
32 pos += ret;
cdb007c1923d random_fill(): If read(/dev/urandom) returned EINTR, it could have written
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
33 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 void random_init(void)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 {
3040
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
39 unsigned int seed;
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
40
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 if (init_refcount++ > 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 return;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43
9204
1849c4269ad8 If /dev/arandom exists (OpenBSD), use it instead of /dev/urandom.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
44 urandom_fd = open(DEV_URANDOM_PATH, O_RDONLY);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 if (urandom_fd == -1) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 if (errno == ENOENT) {
9204
1849c4269ad8 If /dev/arandom exists (OpenBSD), use it instead of /dev/urandom.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
47 i_fatal(DEV_URANDOM_PATH" doesn't exist, "
805
5ac361acb316 Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents: 781
diff changeset
48 "currently we require it");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 } else {
9204
1849c4269ad8 If /dev/arandom exists (OpenBSD), use it instead of /dev/urandom.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
50 i_fatal("Can't open "DEV_URANDOM_PATH": %m");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53
3040
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
54 random_fill(&seed, sizeof(seed));
17531
14f505c1c6f4 lib: use new srand() wrapper in lib
Phil Carmody <phil@dovecot.fi>
parents: 17130
diff changeset
55 rand_set_seed(seed);
3040
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
56
730
02fe757df1f0 Set close-on-exec flag to failure log, /dev/urandom fd already tried to do
Timo Sirainen <tss@iki.fi>
parents: 183
diff changeset
57 fd_close_on_exec(urandom_fd, TRUE);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 void random_deinit(void)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 if (--init_refcount > 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 return;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64
14691
3945a3646c67 Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents: 14687
diff changeset
65 i_close_fd(&urandom_fd);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 }
1335
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
67
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
68 #elif defined(HAVE_OPENSSL_RAND_H)
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
69 #include <openssl/rand.h>
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
70 #include <openssl/err.h>
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
71
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
72 static const char *ssl_last_error(void)
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
73 {
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
74 unsigned long err;
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
75 char *buf;
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
76 size_t err_size = 256;
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
77
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
78 err = ERR_get_error();
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
79 if (err == 0)
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
80 return strerror(errno);
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
81
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
82 buf = t_malloc(err_size);
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
83 buf[err_size-1] = '\0';
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
84 ERR_error_string_n(err, buf, err_size-1);
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
85 return buf;
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
86 }
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
87
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
88 void random_fill(void *buf, size_t size)
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
89 {
1557
fa8322b3b7ec Use RAND_bytes() rather than RAND_pseudo_bytes().
Timo Sirainen <tss@iki.fi>
parents: 1427
diff changeset
90 if (RAND_bytes(buf, size) != 1)
1335
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
91 i_fatal("RAND_pseudo_bytes() failed: %s", ssl_last_error());
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
92 }
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
93
3040
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
94 void random_init(void)
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
95 {
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
96 unsigned int seed;
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
97
7077
aa9a4d419905 If OpenSSL's random number generator can't initialize itself, fail instead
Timo Sirainen <tss@iki.fi>
parents: 6825
diff changeset
98 if (RAND_status() == 0) {
aa9a4d419905 If OpenSSL's random number generator can't initialize itself, fail instead
Timo Sirainen <tss@iki.fi>
parents: 6825
diff changeset
99 i_fatal("Random generator not initialized: "
aa9a4d419905 If OpenSSL's random number generator can't initialize itself, fail instead
Timo Sirainen <tss@iki.fi>
parents: 6825
diff changeset
100 "Install egd on /var/run/egd-pool");
aa9a4d419905 If OpenSSL's random number generator can't initialize itself, fail instead
Timo Sirainen <tss@iki.fi>
parents: 6825
diff changeset
101 }
4101
321469dcb8fb If /dev/urandom didn't exist and we used OpenSSL's random number generator,
Timo Sirainen <tss@iki.fi>
parents: 3040
diff changeset
102
3040
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
103 random_fill(&seed, sizeof(seed));
17531
14f505c1c6f4 lib: use new srand() wrapper in lib
Phil Carmody <phil@dovecot.fi>
parents: 17130
diff changeset
104 rand_set_seed(seed);
3040
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
105 }
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
106
1335
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
107 void random_deinit(void) {}
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
108
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
109 #else
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1557
diff changeset
110 # error No random number generator, use eg. OpenSSL.
1335
5ad84c54eb7e Support using OpenSSL's pseudo-random generator instead of /dev/urandom. If
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
111 #endif
3040
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
112
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
113 void random_fill_weak(void *buf, size_t size)
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
114 {
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
115 unsigned char *cbuf = buf;
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
116
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
117 for (; size > 0; size--)
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
118 *cbuf++ = (unsigned char)rand();
50acbcc7e4d8 Added random_fill_weak() and make random_init() always initialize srand()
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
119 }