Mercurial > dovecot > core-2.2
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 |
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 | 2 |
3 #include "lib.h" | |
4 #include "randgen.h" | |
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 | 10 #include <unistd.h> |
11 #include <fcntl.h> | |
12 | |
13 static int init_refcount = 0; | |
14 static int urandom_fd; | |
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 | 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 | 20 |
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 | 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 | 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 | 34 } |
35 } | |
36 | |
37 void random_init(void) | |
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 | 41 if (init_refcount++ > 0) |
42 return; | |
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 | 45 if (urandom_fd == -1) { |
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 | 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 | 51 } |
52 } | |
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 | 58 } |
59 | |
60 void random_deinit(void) | |
61 { | |
62 if (--init_refcount > 0) | |
63 return; | |
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 | 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 } |