d9898ee8 |
1 | /* |
2 | ** Copyright 1998 - 2006 Double Precision, Inc. |
3 | ** See COPYING for distribution information. |
4 | */ |
5 | |
6 | #if HAVE_CONFIG_H |
7 | #include "config.h" |
8 | #endif |
9 | |
10 | #if HAVE_UNISTD_H |
11 | #include <unistd.h> |
12 | #endif |
13 | #if HAVE_FCNTL_H |
14 | #include <fcntl.h> |
15 | #endif |
16 | #include <time.h> |
17 | #include <string.h> |
18 | #include <errno.h> |
19 | #include <stdio.h> |
20 | #include <sys/types.h> |
21 | #include <sys/wait.h> |
22 | |
23 | #define MD5_INTERNAL |
24 | #include "md5/md5.h" |
25 | |
26 | #include "random128.h" |
27 | |
d9898ee8 |
28 | |
29 | const char *random128() |
30 | { |
31 | static char randombuf[sizeof(MD5_DIGEST)*2+1]; |
32 | |
33 | #ifdef RANDOM |
34 | { |
35 | int fd=open(RANDOM, O_RDONLY); |
36 | char buf2[sizeof(MD5_DIGEST)]; |
37 | int i; |
38 | |
39 | if (fd >= 0) |
40 | { |
41 | if (read(fd, buf2, sizeof(buf2)) == sizeof(buf2)) |
42 | { |
43 | for (i=0; i<sizeof(buf2); i++) |
44 | sprintf(randombuf+i*2, |
45 | "%02X", |
46 | (int)(unsigned char)buf2[i]); |
47 | close(fd); |
48 | return (randombuf); |
49 | } |
50 | close(fd); |
51 | } |
52 | } |
53 | #endif |
54 | |
55 | /* /dev/urandom not available or broken? Create some noise */ |
56 | |
57 | { |
58 | int pipefd[2]; |
59 | int s; |
60 | char buf[512]; |
61 | struct MD5_CONTEXT context; |
62 | MD5_DIGEST digest; |
63 | int n; |
64 | time_t t; |
65 | pid_t p, p2; |
66 | unsigned long l; |
67 | |
68 | time(&t); |
69 | p=getpid(); |
70 | |
71 | if (pipe(pipefd)) return (0); |
72 | while ((p=fork()) == -1) |
73 | { |
74 | sleep (5); |
75 | } |
76 | if (p == 0) |
77 | { |
78 | dup2(pipefd[1], 1); |
79 | dup2(pipefd[1], 2); |
80 | close(pipefd[0]); |
81 | close(pipefd[1]); |
82 | |
83 | #ifdef W |
84 | while ((p=fork()) == -1) |
85 | { |
86 | sleep (5); |
87 | } |
88 | if (p == 0) |
89 | { |
90 | execl(W, W, (char *)0); |
91 | perror(W); |
92 | _exit(0); |
93 | } |
94 | while (wait(&s) >= 0) |
95 | ; |
96 | #endif |
97 | |
98 | execl(PS, PS, PS_OPTIONS, (char *)0); |
99 | perror(PS); |
100 | _exit(0); |
101 | } |
102 | close(pipefd[1]); |
103 | md5_context_init(&context); |
104 | md5_context_hashstream(&context, &t, sizeof(t)); |
105 | md5_context_hashstream(&context, &p, sizeof(p)); |
106 | l=sizeof(t)+sizeof(p); |
107 | |
108 | while ((n=read(pipefd[0], buf, sizeof(buf))) > 0) |
109 | { |
110 | md5_context_hashstream(&context, buf, n); |
111 | l += n; |
112 | } |
113 | md5_context_endstream(&context, l); |
114 | md5_context_digest(&context, digest); |
115 | close(pipefd[0]); |
116 | while ((p2=wait(&s)) >= 0 && p != p2) |
117 | ; |
118 | |
119 | for (n=0; n<sizeof(digest); n++) |
120 | sprintf(randombuf+n*2, |
121 | "%02X", (int)(unsigned char)digest[n]); |
122 | } |
123 | |
124 | return (randombuf); |
125 | } |