]> git.sesse.net Git - rdpsrv/blobdiff - util.c
Moved socket functions around a bit.
[rdpsrv] / util.c
diff --git a/util.c b/util.c
index 2376a6193ba27e583e7e0c6c306664339a6f966a..24365bf35a5a8486079bd75e5978c336e8d3acb6 100644 (file)
--- a/util.c
+++ b/util.c
@@ -75,6 +75,51 @@ generate_random_egd(uint8 * buf)
 }
 #endif
 
+/* Generate a 32-byte random for the secure transport code. */
+void
+generate_random(uint8 * random)
+{
+       struct stat st;
+       struct tms tmsbuf;
+       MD5_CTX md5;
+       uint32 *r;
+       int fd, n;
+
+       /* If we have a kernel random device, try that first */
+       if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
+                       || ((fd = open("/dev/random", O_RDONLY)) != -1))
+       {
+               n = read(fd, random, 32);
+               close(fd);
+               if (n == 32)
+                       return;
+       }
+
+#ifdef EGD_SOCKET
+       /* As a second preference use an EGD */
+       if (generate_random_egd(random))
+               return;
+#endif
+
+       /* Otherwise use whatever entropy we can gather - ideas welcome. */
+       r = (uint32 *) random;
+       r[0] = (getpid()) | (getppid() << 16);
+       r[1] = (getuid()) | (getgid() << 16);
+       r[2] = times(&tmsbuf);  /* system uptime (clocks) */
+       gettimeofday((struct timeval *) &r[3], NULL);   /* sec and usec */
+       stat("/tmp", &st);
+       r[5] = st.st_atime;
+       r[6] = st.st_mtime;
+       r[7] = st.st_ctime;
+
+       /* Hash both halves with MD5 to obscure possible patterns */
+       MD5_Init(&md5);
+       MD5_Update(&md5, random, 16);
+       MD5_Final(random, &md5);
+       MD5_Update(&md5, random + 16, 16);
+       MD5_Final(random + 16, &md5);
+}
+
 /* malloc; exit if out of memory */
 void *
 xmalloc(int size)