diff options
Diffstat (limited to 'helper.c')
-rw-r--r-- | helper.c | 39 |
1 files changed, 34 insertions, 5 deletions
@@ -41,6 +41,8 @@ | |||
41 | 41 | ||
42 | #include <sys/types.h> | 42 | #include <sys/types.h> |
43 | #include <sys/stat.h> | 43 | #include <sys/stat.h> |
44 | #include <sys/socket.h> | ||
45 | #include <sys/un.h> | ||
44 | #include <fcntl.h> | 46 | #include <fcntl.h> |
45 | 47 | ||
46 | #include "rc4.h" | 48 | #include "rc4.h" |
@@ -49,6 +51,10 @@ | |||
49 | #include "config.h" | 51 | #include "config.h" |
50 | #include "helper.h" | 52 | #include "helper.h" |
51 | 53 | ||
54 | #ifndef offsetof | ||
55 | #define offsetof(type, member) ((size_t) &((type *)0)->member) | ||
56 | #endif | ||
57 | |||
52 | #ifndef HAVE_ARC4RANDOM | 58 | #ifndef HAVE_ARC4RANDOM |
53 | 59 | ||
54 | void get_random_bytes(unsigned char *buf, int len); | 60 | void get_random_bytes(unsigned char *buf, int len); |
@@ -80,17 +86,33 @@ void arc4random_stir(void) | |||
80 | 86 | ||
81 | void get_random_bytes(unsigned char *buf, int len) | 87 | void get_random_bytes(unsigned char *buf, int len) |
82 | { | 88 | { |
83 | int random_pool; | 89 | static int random_pool; |
84 | int c; | 90 | int c; |
85 | #ifdef HAVE_EGD | 91 | #ifdef HAVE_EGD |
86 | char egd_message[2] = { 0x02, 0x00 }; | 92 | char egd_message[2] = { 0x02, 0x00 }; |
87 | #endif /* HAVE_EGD */ | 93 | struct sockaddr_un addr; |
94 | int addr_len; | ||
95 | |||
96 | memset(&addr, '\0', sizeof(addr)); | ||
97 | addr.sun_family = AF_UNIX; | ||
98 | |||
99 | /* FIXME: compile time check? */ | ||
100 | if (sizeof(RANDOM_POOL) > sizeof(addr.sun_path)) | ||
101 | fatal("Random pool path is too long"); | ||
102 | |||
103 | strncpy(addr.sun_path, RANDOM_POOL, sizeof(addr.sun_path - 1)); | ||
104 | addr.sun_path[sizeof(addr.sun_path - 1)] = '\0'; | ||
105 | |||
106 | addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(RANDOM_POOL); | ||
107 | |||
108 | random_pool = socket(AF_UNIX, SOCK_STREAM, 0); | ||
88 | 109 | ||
89 | random_pool = open(RANDOM_POOL, O_RDONLY); | ||
90 | if (random_pool == -1) | 110 | if (random_pool == -1) |
91 | fatal("Couldn't open random pool \"%s\": %s", RANDOM_POOL, strerror(errno)); | 111 | fatal("Couldn't create AF_UNIX socket: %s", strerror(errno)); |
92 | 112 | ||
93 | #ifdef HAVE_EGD | 113 | if (connect(random_pool, (struct sockaddr*)&addr, addr_len) == -1) |
114 | fatal("Couldn't connect to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno)); | ||
115 | |||
94 | if (len > 255) | 116 | if (len > 255) |
95 | fatal("Too many bytes to read from EGD"); | 117 | fatal("Too many bytes to read from EGD"); |
96 | 118 | ||
@@ -99,6 +121,13 @@ void get_random_bytes(unsigned char *buf, int len) | |||
99 | c = write(random_pool, egd_message, sizeof(egd_message)); | 121 | c = write(random_pool, egd_message, sizeof(egd_message)); |
100 | if (c == -1) | 122 | if (c == -1) |
101 | fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno)); | 123 | fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno)); |
124 | |||
125 | #else /* HAVE_EGD */ | ||
126 | |||
127 | random_pool = open(RANDOM_POOL, O_RDONLY); | ||
128 | if (random_pool == -1) | ||
129 | fatal("Couldn't open random pool \"%s\": %s", RANDOM_POOL, strerror(errno)); | ||
130 | |||
102 | #endif /* HAVE_EGD */ | 131 | #endif /* HAVE_EGD */ |
103 | 132 | ||
104 | c = read(random_pool, buf, len); | 133 | c = read(random_pool, buf, len); |