dtlogin: don't try to use /dev/mem to get random data on linux/bsd
authorJon Trulson <jon@radscan.com>
Wed, 8 Aug 2012 05:22:44 +0000 (23:22 -0600)
committerJon Trulson <jon@radscan.com>
Wed, 8 Aug 2012 05:22:44 +0000 (23:22 -0600)
dtlogin's genauth routines were trying to open and read /dev/mem on
linux and (presumably) bsd systems in order to obtain random data used
in creating an auth key.

This is bad for a variety of reasons.  Newer linux kernels (at least
on 3.2) issue the following warning to the kernel logs:

"Program dtlogin tried to access /dev/mem between 100000->102000."

Now on linux we will use /dev/urandom, and on CSRG_BASED (bsd) systems
we will use /dev/random to obtain some entropy.

cde/programs/dtlogin/genauth.c

index b000e347cee8d8aaa4a87d861139c0005ce19315..ae2ed2196404f70d441bd83c366ce62aaeae5bac 100644 (file)
@@ -223,6 +223,52 @@ char       bytes[64];
 
 # define FILE_LIMIT    1024    /* no more than this many buffers */
 
+/* for linux/csrg we use a simpler method to get 2 random longs from
+ *  the OS's random number device.
+ */
+
+#if defined(linux) || defined(CSRG_BASED)
+#define READ_LIMIT (sizeof (long) * 2)
+
+static sumFile (char *name, long sum[2])
+{
+  long    buf[2];
+  int    fd;
+  int     ret_status = 0;
+
+  if ( (fd = open (name, 0)) < 0 )
+    {
+      LogError((unsigned char *) "Cannot open randomFile \"%s\", errno = %d\n",
+               name, errno);
+      return 0;
+    }
+
+  sum[0] = 0;
+  sum[1] = 0;
+
+  if (read(fd, (char *)buf, READ_LIMIT) != READ_LIMIT)
+    {
+      LogError((unsigned char *) "Could not read %d bytes from '%s'\n",
+               READ_LIMIT, name);
+      /* cheap fallback */
+      sum[0] = (long)time((Time_t *) 0);
+      sum[1] = sum[0];
+    }
+  else
+    {
+      sum[0] = buf[0];
+      sum[1] = buf[1];
+      ret_status = 1;
+    }
+
+  close(fd);
+  return ret_status;
+}
+
+#undef READ_LIMIT
+
+#else /* linux || CSRG_BASED */
+
 static
 sumFile (name, sum)
 char   *name;
@@ -260,7 +306,7 @@ long        sum[2];
     close (fd);
     return ret_status;
 }
-
+#endif /* linux || CSRG_BASED */
 
 GenerateAuthData (auth, len)
 char   *auth;
@@ -395,8 +441,17 @@ static int  cryptoInited = 0;
 int 
 InitCryptoKey( void )
 {
+#if defined(linux) 
+    /* non-blocking */
+    char    *key_file = "/dev/urandom";
+#elif defined(CSRG_BASED)
+    /* non-blocking */
+    char    *key_file = "/dev/random";
+#else
+# warning "Using /dev/mem for random bits."
+    /* JET - this seems like a really bad idea. */
     char    *key_file = "/dev/mem";
-    
+#endif    
     if (cryptoInited)
        return;