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 | |
28 | static const char rcsid[]="$Id: random128.c,v 1.6 2006/05/28 15:29:52 mrsam Exp $"; |
29 | |
30 | const char *random128() |
31 | { |
32 | static char randombuf[sizeof(MD5_DIGEST)*2+1]; |
33 | |
34 | #ifdef RANDOM |
35 | { |
36 | int fd=open(RANDOM, O_RDONLY); |
37 | char buf2[sizeof(MD5_DIGEST)]; |
38 | int i; |
39 | |
40 | if (fd >= 0) |
41 | { |
42 | if (read(fd, buf2, sizeof(buf2)) == sizeof(buf2)) |
43 | { |
44 | for (i=0; i<sizeof(buf2); i++) |
45 | sprintf(randombuf+i*2, |
46 | "%02X", |
47 | (int)(unsigned char)buf2[i]); |
48 | close(fd); |
49 | return (randombuf); |
50 | } |
51 | close(fd); |
52 | } |
53 | } |
54 | #endif |
55 | |
56 | /* /dev/urandom not available or broken? Create some noise */ |
57 | |
58 | { |
59 | int pipefd[2]; |
60 | int s; |
61 | char buf[512]; |
62 | struct MD5_CONTEXT context; |
63 | MD5_DIGEST digest; |
64 | int n; |
65 | time_t t; |
66 | pid_t p, p2; |
67 | unsigned long l; |
68 | |
69 | time(&t); |
70 | p=getpid(); |
71 | |
72 | if (pipe(pipefd)) return (0); |
73 | while ((p=fork()) == -1) |
74 | { |
75 | sleep (5); |
76 | } |
77 | if (p == 0) |
78 | { |
79 | dup2(pipefd[1], 1); |
80 | dup2(pipefd[1], 2); |
81 | close(pipefd[0]); |
82 | close(pipefd[1]); |
83 | |
84 | #ifdef W |
85 | while ((p=fork()) == -1) |
86 | { |
87 | sleep (5); |
88 | } |
89 | if (p == 0) |
90 | { |
91 | execl(W, W, (char *)0); |
92 | perror(W); |
93 | _exit(0); |
94 | } |
95 | while (wait(&s) >= 0) |
96 | ; |
97 | #endif |
98 | |
99 | execl(PS, PS, PS_OPTIONS, (char *)0); |
100 | perror(PS); |
101 | _exit(0); |
102 | } |
103 | close(pipefd[1]); |
104 | md5_context_init(&context); |
105 | md5_context_hashstream(&context, &t, sizeof(t)); |
106 | md5_context_hashstream(&context, &p, sizeof(p)); |
107 | l=sizeof(t)+sizeof(p); |
108 | |
109 | while ((n=read(pipefd[0], buf, sizeof(buf))) > 0) |
110 | { |
111 | md5_context_hashstream(&context, buf, n); |
112 | l += n; |
113 | } |
114 | md5_context_endstream(&context, l); |
115 | md5_context_digest(&context, digest); |
116 | close(pipefd[0]); |
117 | while ((p2=wait(&s)) >= 0 && p != p2) |
118 | ; |
119 | |
120 | for (n=0; n<sizeof(digest); n++) |
121 | sprintf(randombuf+n*2, |
122 | "%02X", (int)(unsigned char)digest[n]); |
123 | } |
124 | |
125 | return (randombuf); |
126 | } |