Imported Upstream version 0.66.1
[hcoop/debian/courier-authlib.git] / libs / random128 / random128.c
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
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 }