]>
Commit | Line | Data |
---|---|---|
8efc0c15 | 1 | /* |
2 | ** | |
3 | ** OpenBSD emulation routines | |
4 | ** | |
5 | ** Damien Miller <djm@ibs.com.au> | |
6 | ** | |
7 | ** Copyright 1999 Internet Business Solutions | |
8 | ** | |
9 | ** Permission is hereby granted, free of charge, to any person | |
10 | ** obtaining a copy of this software and associated documentation | |
11 | ** files (the "Software"), to deal in the Software without | |
12 | ** restriction, including without limitation the rights to use, copy, | |
13 | ** modify, merge, publish, distribute, sublicense, and/or sell copies | |
14 | ** of the Software, and to permit persons to whom the Software is | |
15 | ** furnished to do so, subject to the following conditions: | |
16 | ** | |
17 | ** The above copyright notice and this permission notice shall be | |
18 | ** included in all copies or substantial portions of the Software. | |
19 | ** | |
20 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | |
21 | ** KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | |
22 | ** WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE | |
23 | ** AND NONINFRINGEMENT. IN NO EVENT SHALL DAMIEN MILLER OR INTERNET | |
24 | ** BUSINESS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
25 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
26 | ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE | |
27 | ** OR OTHER DEALINGS IN THE SOFTWARE. | |
28 | ** | |
29 | ** Except as contained in this notice, the name of Internet Business | |
30 | ** Solutions shall not be used in advertising or otherwise to promote | |
31 | ** the sale, use or other dealings in this Software without prior | |
32 | ** written authorization from Internet Business Solutions. | |
33 | ** | |
34 | */ | |
35 | ||
36 | #include <stdio.h> | |
37 | #include <stdlib.h> | |
38 | #include <string.h> | |
39 | #include <errno.h> | |
40 | #include <unistd.h> | |
41 | ||
42 | #include <sys/types.h> | |
43 | #include <sys/stat.h> | |
7b1cc56c | 44 | #include <sys/socket.h> |
45 | #include <sys/un.h> | |
8efc0c15 | 46 | #include <fcntl.h> |
47 | ||
48 | #include "rc4.h" | |
49 | #include "xmalloc.h" | |
4cca272e | 50 | #include "ssh.h" |
fb723d82 | 51 | #include "config.h" |
8efc0c15 | 52 | #include "helper.h" |
53 | ||
7b1cc56c | 54 | #ifndef offsetof |
55 | #define offsetof(type, member) ((size_t) &((type *)0)->member) | |
56 | #endif | |
57 | ||
fb723d82 | 58 | #ifndef HAVE_ARC4RANDOM |
59 | ||
8efc0c15 | 60 | void get_random_bytes(unsigned char *buf, int len); |
61 | ||
62 | static rc4_t *rc4 = NULL; | |
63 | ||
0183ea1c | 64 | unsigned int arc4random(void) |
8efc0c15 | 65 | { |
0183ea1c | 66 | unsigned int r; |
8efc0c15 | 67 | |
68 | if (rc4 == NULL) | |
69 | arc4random_stir(); | |
70 | ||
0183ea1c | 71 | rc4_getbytes(rc4, (unsigned char *)&r, sizeof(r)); |
8efc0c15 | 72 | |
73 | return(r); | |
74 | } | |
75 | ||
76 | void arc4random_stir(void) | |
77 | { | |
78 | unsigned char rand_buf[32]; | |
79 | ||
80 | if (rc4 == NULL) | |
81 | rc4 = xmalloc(sizeof(*rc4)); | |
82 | ||
83 | get_random_bytes(rand_buf, sizeof(rand_buf)); | |
84 | rc4_key(rc4, rand_buf, sizeof(rand_buf)); | |
85 | } | |
86 | ||
87 | void get_random_bytes(unsigned char *buf, int len) | |
88 | { | |
7b1cc56c | 89 | static int random_pool; |
8efc0c15 | 90 | int c; |
4cca272e | 91 | #ifdef HAVE_EGD |
92 | char egd_message[2] = { 0x02, 0x00 }; | |
7b1cc56c | 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 | ||
530f1889 | 103 | strcpy(addr.sun_path, RANDOM_POOL); |
7b1cc56c | 104 | |
105 | addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(RANDOM_POOL); | |
106 | ||
107 | random_pool = socket(AF_UNIX, SOCK_STREAM, 0); | |
8efc0c15 | 108 | |
4cca272e | 109 | if (random_pool == -1) |
7b1cc56c | 110 | fatal("Couldn't create AF_UNIX socket: %s", strerror(errno)); |
8efc0c15 | 111 | |
7b1cc56c | 112 | if (connect(random_pool, (struct sockaddr*)&addr, addr_len) == -1) |
b609e28f | 113 | fatal("Couldn't connect to EGD socket \"%s\": %s", addr.sun_path, strerror(errno)); |
7b1cc56c | 114 | |
4cca272e | 115 | if (len > 255) |
116 | fatal("Too many bytes to read from EGD"); | |
117 | ||
118 | /* Send blocking read request to EGD */ | |
119 | egd_message[1] = len; | |
120 | c = write(random_pool, egd_message, sizeof(egd_message)); | |
121 | if (c == -1) | |
122 | fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno)); | |
7b1cc56c | 123 | |
124 | #else /* HAVE_EGD */ | |
125 | ||
126 | random_pool = open(RANDOM_POOL, O_RDONLY); | |
127 | if (random_pool == -1) | |
128 | fatal("Couldn't open random pool \"%s\": %s", RANDOM_POOL, strerror(errno)); | |
129 | ||
4cca272e | 130 | #endif /* HAVE_EGD */ |
131 | ||
530f1889 | 132 | do { |
133 | c = read(random_pool, buf, len); | |
134 | ||
135 | if ((c == -1) && (errno != EINTR)) | |
136 | fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno)); | |
137 | } while (c == -1); | |
8efc0c15 | 138 | |
139 | if (c != len) | |
4cca272e | 140 | fatal("Short read from random pool \"%s\"", RANDOM_POOL); |
141 | ||
142 | close(random_pool); | |
8efc0c15 | 143 | } |
fb723d82 | 144 | #endif /* !HAVE_ARC4RANDOM */ |
8efc0c15 | 145 | |
fb723d82 | 146 | #ifndef HAVE_SETPROCTITLE |
147 | void setproctitle(const char *fmt, ...) | |
148 | { | |
149 | /* FIXME */ | |
150 | } | |
151 | #endif /* !HAVE_SETPROCTITLE */ |