+#if !defined(ARC4_RANDOM) && !defined(DEV_RANDOM)
+ AddOtherEntropy ();
+#endif
+
/*
* We used to clean up old authorization files here. As authDir is
* supposed to be /var/run/xauth or /tmp, we needn't to care for it.
*/
-static unsigned char key[8];
-
-#ifdef HASXDMAUTH
-
-#ifndef X_GETTIMEOFDAY
-/* WABA: According to the man page gettimeofday takes a second argument */
-/* if this breaks on your system, we need to have a configure test. */
-# define X_GETTIMEOFDAY(t) gettimeofday(t, NULL)
-#endif
+#if !defined(ARC4_RANDOM) && !defined(DEV_RANDOM)
-typedef struct auth_ks_struct { auth_cblock _; } auth_wrapper_schedule[16];
+/*
+ * Stolen from the Linux kernel.
+ *
+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All
+ * rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
-# define FILE_LIMIT 1024 /* no more than this many buffers */
+/*
+ * This code implements something close to the MD5 message-digest
+ * algorithm. This code is based on code written by Colin Plumb
+ * in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ */
-#if !defined(ARC4_RANDOM) && !defined(DEV_RANDOM)
-static int
-sumFile (const char *name, long sum[2])
-{
- long buf[1024*2];
- int cnt;
- int fd;
- int loops;
- int reads;
- int i;
- int ret_status = 0;
-
- fd = open (name, O_RDONLY);
- if (fd < 0) {
- LogError("Cannot open randomFile \"%s\", errno = %d\n", name, errno);
- return 0;
- }
-#ifdef FRAGILE_DEV_MEM
- if (!strcmp(name, "/dev/mem"))
- lseek (fd, (off_t) 0x100000, SEEK_SET);
-#endif
- reads = FILE_LIMIT;
- sum[0] = 0;
- sum[1] = 0;
- while ((cnt = read (fd, (char *) buf, sizeof (buf))) > 0 && --reads > 0) {
- loops = cnt / (2 * sizeof (long));
- for (i = 0; i < loops; i+= 2) {
- sum[0] += buf[i];
- sum[1] += buf[i+1];
- ret_status = 1;
- }
- }
- if (cnt < 0)
- LogError("Cannot read randomFile \"%s\", errno = %d\n", name, errno);
- close (fd);
- return ret_status;
-}
-#endif
+/* The four core functions - F1 is optimized somewhat */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1 (z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define pmd5_step(f, w, x, y, z, data, s) \
+ ( w += (f(x, y, z) + data) & 0xffffffff, w = w<<s | w>>(32-s), w += x )
-#ifdef HASXDMAUTH
-static void
-InitXdmcpWrapper (void)
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.
+ */
+static void
+pmd5_hash (unsigned *out, unsigned const in[16])
{
+ unsigned a, b, c, d;
+#ifndef X_GETTIMEOFDAY
+/* WABA: According to the man page gettimeofday takes a second argument */
+/* if this breaks on your system, we need to have a configure test. */
+# define X_GETTIMEOFDAY(t) gettimeofday(t, NULL)
#endif
-#ifndef HASXDMAUTH
-/* A random number generator that is more unpredictable
- than that shipped with some systems.
- This code is taken from the C standard. */
-
-static unsigned long int next = 1;
-
-static int
-xdm_rand(void)
+void
+AddTimerEntropy (void)
{
- next = next * 1103515245 + 12345;
- return (unsigned int)(next/65536) % 32768;
+ struct timeval now;
+ X_GETTIMEOFDAY (&now);
+ add_entropy((unsigned*)&now, sizeof(now)/sizeof(unsigned));
}
-static void
-xdm_srand(unsigned int seed)
+#define BSIZ 0x10000
+
+void
+AddOtherEntropy (void)
{
- next = seed;
+ AddTimerEntropy();
+ /* XXX -- these will work only on linux and similar, but those already have urandom ... */
+ sumFile ("/proc/stat", BSIZ, SEEK_SET, 0);
+ sumFile ("/proc/interrupts", BSIZ, SEEK_SET, 0);
+ sumFile ("/proc/loadavg", BSIZ, SEEK_SET, 0);
+ sumFile ("/proc/net/dev", BSIZ, SEEK_SET, 0);
+ /* XXX -- setup-specific ... use some common ones */
+ sumFile ("/var/log/messages", 0x1000, SEEK_END, -0x1000);
+ sumFile ("/var/log/syslog", 0x1000, SEEK_END, -0x1000);
+ sumFile ("/var/log/debug", 0x1000, SEEK_END, -0x1000);
+ sumFile ("/var/log/kern.log", 0x1000, SEEK_END, -0x1000);
+ sumFile ("/var/log/daemon.log", 0x1000, SEEK_END, -0x1000);
+/* root hardly ever has an own box ... maybe pick a random mailbox instead? eek ...
+ sumFile ("/var/spool/mail/root", 0x1000, SEEK_END, -0x1000);
+*/
}
-#endif /* no HASXDMAUTH */
void
-GenerateAuthData (char *auth, int len)
+AddPreGetEntropy (void)
{
- long ldata[2];
-
-#ifdef ITIMER_REAL
- {
- struct timeval now;
+ static long offset;
+ long readlen;
- X_GETTIMEOFDAY (&now);
- ldata[0] = now.tv_usec;
- ldata[1] = now.tv_sec;
- }
-#else
- {
-#ifndef __EMX__
- long time ();
+ AddTimerEntropy();
+ if ((readlen = sumFile (randomFile, BSIZ, SEEK_SET, offset)) == BSIZ) {
+ offset += readlen;
+#ifdef FRAGILE_DEV_MEM
+ if (!strcmp (randomFile, "/dev/mem")) {
+ if (offset == 0xa0000) /* skip 640kB-1MB ROM mappings */
+ offset = 0x100000;
+ else if (offset == 0xf00000) /* skip 15-16MB memory hole */
+ offset = 0x1000000;
+ }
#endif
-
- ldata[0] = time ((long *) 0);
- ldata[1] = getpid ();
+ return;
+ } else if (readlen >= 0 && offset) {
+ if ((offset = sumFile (randomFile, BSIZ, SEEK_SET, 0)) == BSIZ)
+ return;
}
+ LogError("Cannot read randomFile %\"s; X cookies may be easily guessable\n", randomFile);
+}
#endif
-#ifdef HASXDMAUTH
- {
- int bit;
- int i;
- auth_wrapper_schedule schedule;
- unsigned char data[8];
- static int xdmcpAuthInited;
-
- longtochars (ldata[0], data+0);
- longtochars (ldata[1], data+4);
- if (!xdmcpAuthInited)
- {
- InitXdmcpWrapper ();
- xdmcpAuthInited = 1;
- }
- _XdmcpAuthSetup (key, schedule);
- for (i = 0; i < len; i++) {
- auth[i] = 0;
- for (bit = 1; bit < 256; bit <<= 1) {
- _XdmcpAuthDoIt (data, data, schedule, 1);
- if ((data[0] + data[1]) & 0x4)
- auth[i] |= bit;
- }
- }
- }
-#else
- {
- int seed;
- int value;
- int i;
- static long localkey[2] = {0, 0};
-
- if ( (localkey[0] == 0) && (localkey[1] == 0) ) {
+
+/* ONLY 8 or 16 bytes! */
+/* auth MUST be sizeof(unsigned)-aligned! */
+int
+GenerateAuthData (char *auth, int len)
+{
+ unsigned *rnd = (unsigned*)auth;
+
#ifdef ARC4_RANDOM
- localkey[0] = arc4random();
- localkey[1] = arc4random();
-#elif defined(DEV_RANDOM)
- int fd;
-
- if ((fd = open("/dev/urandom", O_RDONLY)) >= 0) {
- if (read(fd, (char *)localkey, 8) != 8) {
- localkey[0] = 1;
- }
+ int i;
+ if (sizeof(unsigned) == 4)
+ for (i = 0; i < len; i += 4)
+ rnd[i / 4] = arc4random();
+ else
+ for (i = 0; i < len; i += 8)
+ rnd[i / 8] = arc4random() | (arc4random() << 32);
+ return 1;
+#else
+ int fd;
+ const char *rd = randomDevice;
+# ifdef DEV_RANDOM
+ if (!*rd)
+ rd = DEV_RANDOM;
+# else
+ if (*rd) {
+# endif
+ if ((fd = open(rd, O_RDONLY)) >= 0) {
+ if (read(fd, auth, len) == len) {
close(fd);
- } else {
- localkey[0] = 1;
+ return 1;
}
-#else
- if (!sumFile (randomFile, localkey)) {
- localkey[0] = 1; /* To keep from continually calling sumFile() */
- }
-#endif
- }
+ close(fd);
+ LogError("Cannot read randomDevice %\"s, errno=%d\n", rd, errno);
+ } else
+ LogError("Cannot open randomDevice %\"s, errno=%d\n", rd, errno);
+# ifdef DEV_RANDOM
+ return 0;
+# else
+ }