Back to index

courier  0.68.2
random128.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2006 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #if    HAVE_CONFIG_H
00007 #include      "config.h"
00008 #endif
00009 
00010 #if    HAVE_UNISTD_H
00011 #include      <unistd.h>
00012 #endif
00013 #if    HAVE_FCNTL_H
00014 #include      <fcntl.h>
00015 #endif
00016 #include      <time.h>
00017 #include      <string.h>
00018 #include      <errno.h>
00019 #include      <stdio.h>
00020 #include      <sys/types.h>
00021 #include      <sys/wait.h>
00022 
00023 #define       MD5_INTERNAL
00024 #include      "md5/md5.h"
00025 
00026 #include      "random128.h"
00027 
00028 
00029 const char *random128()
00030 {
00031 static char randombuf[sizeof(MD5_DIGEST)*2+1];
00032 
00033 #ifdef RANDOM
00034        {
00035        int    fd=open(RANDOM, O_RDONLY);
00036        char   buf2[sizeof(MD5_DIGEST)];
00037        int    i;
00038 
00039               if (fd >= 0)
00040               {
00041                      if (read(fd, buf2, sizeof(buf2)) == sizeof(buf2))
00042                      {
00043                             for (i=0; i<sizeof(buf2); i++)
00044                                    sprintf(randombuf+i*2,
00045                                           "%02X",
00046                                           (int)(unsigned char)buf2[i]);
00047                             close(fd);
00048                             return (randombuf);
00049                      }
00050                      close(fd);
00051               }
00052        }
00053 #endif
00054 
00055        /* /dev/urandom not available or broken?  Create some noise */
00056 
00057        {
00058        int pipefd[2];
00059        int s;
00060        char   buf[512];
00061        struct MD5_CONTEXT context;
00062        MD5_DIGEST    digest;
00063        int    n;
00064        time_t t;
00065        pid_t  p, p2;
00066        unsigned long l;
00067 
00068               time(&t);
00069               p=getpid();
00070 
00071               if (pipe(pipefd))    return (0);
00072               while ((p=fork()) == -1)
00073               {
00074                      sleep (5);
00075               }
00076               if (p == 0)
00077               {
00078                      dup2(pipefd[1], 1);
00079                      dup2(pipefd[1], 2);
00080                      close(pipefd[0]);
00081                      close(pipefd[1]);
00082 
00083 #ifdef W
00084                      while ((p=fork()) == -1)
00085                      {
00086                             sleep (5);
00087                      }
00088                      if (p == 0)
00089                      {
00090                             execl(W, W, (char *)0);
00091                             perror(W);
00092                             _exit(0);
00093                      }
00094                      while (wait(&s) >= 0)
00095                             ;
00096 #endif
00097 
00098                      execl(PS, PS, PS_OPTIONS, (char *)0);
00099                      perror(PS);
00100                      _exit(0);
00101               }
00102               close(pipefd[1]);
00103               md5_context_init(&context);
00104               md5_context_hashstream(&context, &t, sizeof(t));
00105               md5_context_hashstream(&context, &p, sizeof(p));
00106               l=sizeof(t)+sizeof(p);
00107 
00108               while ((n=read(pipefd[0], buf, sizeof(buf))) > 0)
00109               {
00110                      md5_context_hashstream(&context, buf, n);
00111                      l += n;
00112               }
00113               md5_context_endstream(&context, l);
00114               md5_context_digest(&context, digest);
00115               close(pipefd[0]);
00116               while ((p2=wait(&s)) >= 0 && p != p2)
00117                      ;
00118 
00119               for (n=0; n<sizeof(digest); n++)
00120                      sprintf(randombuf+n*2,
00121                             "%02X", (int)(unsigned char)digest[n]);
00122        }
00123 
00124        return (randombuf);
00125 }