From b952231df1e7d8f890d7af9d7ce5c81f0e08150d Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Sun, 24 Apr 2005 15:56:36 +0000
Subject: [PATCH] * warn if we seem to be blocking on /dev/random

--HG--
extra : convert_revision : a160efd238030ac4f7fd8304c5a87928145feccc
---
 TODO     |  3 ---
 random.c | 19 +++++++++++++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/TODO b/TODO
index 7acc8c03..cfd045b8 100644
--- a/TODO
+++ b/TODO
@@ -4,9 +4,6 @@ Things which might need doing:
 
 - Make options.h generated from configure perhaps?
 
-- some sort of warning when blocking on random? (could be difficult,
-  investigate alarm() perhaps)
-
 - Improved queueing of unauthed connections
 
 - handle /etc/environment in AIX
diff --git a/random.c b/random.c
index c69f6419..e45f4747 100644
--- a/random.c
+++ b/random.c
@@ -50,6 +50,7 @@ static void readrand(unsigned char* buf, unsigned int buflen);
 
 static void readrand(unsigned char* buf, unsigned int buflen) {
 
+	static int already_blocked = 0;
 	int readfd;
 	unsigned int readpos;
 	int readlen;
@@ -92,6 +93,24 @@ static void readrand(unsigned char* buf, unsigned int buflen) {
 	/* read the actual random data */
 	readpos = 0;
 	do {
+		if (!already_blocked)
+		{
+			int ret;
+			struct timeval timeout;
+			fd_set read_fds;
+
+			timeout.tv_sec = 2; /* two seconds should be enough */
+			timeout.tv_usec = 0;
+
+			FD_ZERO(&read_fds);
+			FD_SET(readfd, &read_fds);
+			ret = select(readfd + 1, &read_fds, NULL, NULL, &timeout);
+			if (ret == 0)
+			{
+				dropbear_log(LOG_INFO, "Warning: Reading the random source seems to have blocked.\nIf you experience problems, you probably need to find a better entropy source.");
+				already_blocked = 1;
+			}
+		}
 		readlen = read(readfd, &buf[readpos], buflen - readpos);
 		if (readlen <= 0) {
 			if (readlen < 0 && errno == EINTR) {
-- 
GitLab