View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0000515 | LDMud 3.3 | Other | public | 2007-09-14 02:37 | 2009-01-04 13:34 |
| Reporter | zesstra | Assigned To | zesstra | ||
| Priority | normal | Severity | feature | Reproducibility | N/A |
| Status | resolved | Resolution | fixed | ||
| Product Version | 3.3 | ||||
| Fixed in Version | 3.3.718 | ||||
| Summary | 0000515: Seeding the PRG with a more reliable source of randomness | ||||
| Description | Currently the random number generator ist seeded with the system clock at driver startup. This enables people guessing the seed. While this is probably not a big problem in case of a mud, IMHO it is still desirable to enable users to seed the PRG from /dev/urandom or /dev/urandom. (I know, it is possible to seed with a user-defined seed, but this is limited to a single 32-bit value.) I will attach a small patch, which introduces a command-line argument to choose whether to seed from the current driver time/system clock or with 624 32-bit values from /dev/random or /dev/urandom. | ||||
| Tags | No tags attached. | ||||
| Attached Files | randomseed.diff (7,117 bytes)
--- ldmud-3.3.714.orig/src/main.c 2006-07-10 04:42:05.000000000 +0200
+++ ldmud-3.3.714/src/main.c 2007-09-14 10:13:49.000000000 +0200
@@ -108,8 +108,6 @@
Bool allow_filename_spaces = MY_FALSE; /* Allow spaces in filenames */
-static uint32 random_seed = 0; /* The seed for the pseudo-random generator. */
-
static char * hostname = NULL;
static char * hostaddr = NULL;
/* Hostname and -addr given on the commandline. They are passed as
@@ -274,9 +272,11 @@
put_number(&const1, 1);
current_time = get_current_time();
- random_seed = (uint32)current_time;
- seed_random(random_seed);
-
+
+ // init PRG from system clock - if --random-seed or --randominit is given on
+ // the command-line it will re-seeded later.
+ seed_random(0);
+
do {
dummy_current_object_for_loads = NULL_object;
#ifdef DEBUG
@@ -430,11 +430,6 @@
for (i = 0; i < (int)(sizeof avg_consts / sizeof avg_consts[0]); i++)
avg_consts[i] = exp(- i / 900.0);
- printf("%s Random seed: 0x%lx\n"
- , time_stamp(), (unsigned long)random_seed);
- debug_message("%s Random seed: 0x%lx\n"
- , time_stamp(), (unsigned long)random_seed);
-
#ifdef USE_MYSQL
if (!pkg_mysql_init())
{
@@ -1044,6 +1039,7 @@
, cNoHeart /* --no-heart */
, cNoPreload /* --no-preload */
, cPidFile /* --pidfile */
+ , cRandominit /* --randominit */
, cRandomSeed /* --random-seed */
, cRegexp /* --regexp */
, cResetTime /* --reset-time */
@@ -1482,6 +1478,13 @@
" Write the pid of the driver process into <filename>.\n"
}
+ , { 0, "randominit", cRandominit, MY_TRUE
+ , " --randominit <0|1|2>\n"
+ , " --randominit <0|1|2>\n"
+ " Determines the source of the seed for the random number generator.\n"
+ " 0 - init from clock, 1 - init from /dev/random, 2 - init from /dev/urandom\n"
+ }
+
, { 0, "random-seed", cRandomSeed, MY_TRUE
, " --random-seed <num>\n"
, " --random-seed <num>\n"
@@ -2513,14 +2516,23 @@
free(debug_file);
debug_file = strdup(pValue);
break;
+
+ case cRandominit:
+ // seeds PRG from /dev/urandom, /dev/random or system clock
+#ifdef HAVE_STRTOUL
+ seed_random((ph_uint)strtoul(pValue, (char **)0, 10));
+#else
+ seed_random((ph_uint)strtol(pValue, (char **)0, 10));
+#endif
+ break;
case cRandomSeed:
+ // seeds PRG with given value
#ifdef HAVE_STRTOUL
- random_seed = strtoul(pValue, (char **)0, 0);
+ seed_random_from_int(strtoul(pValue, (char **)0, 0));
#else
- random_seed = (uint32)strtol(pValue, (char **)0, 0);
+ seed_random_from_int((uint32)strtol(pValue, (char **)0, 0));
#endif
- seed_random(random_seed);
break;
case cReserved:
--- ldmud-3.3.714.orig/src/random.h 2006-07-10 04:42:06.000000000 +0200
+++ ldmud-3.3.714/src/random.h 2007-09-14 10:22:10.000000000 +0200
@@ -3,7 +3,12 @@
#include "driver.h"
+#define PRG_SEED_CLOCK 0
+#define PRG_SEED_RANDOM 1
+#define PRG_SEED_URANDOM 2
+
extern uint32 random_number(uint32 n);
-extern void seed_random(uint32 seed);
+extern void seed_random_from_int(uint32 seed);
+extern void seed_random(ph_uint mode);
#endif /* RANDOM_H__ */
--- ldmud-3.3.714.orig/src/random.c 2006-07-10 04:42:06.000000000 +0200
+++ ldmud-3.3.714/src/random.c 2007-09-14 21:29:29.000000000 +0200
@@ -45,7 +45,10 @@
*---------------------------------------------------------------------------
*/
+#include <stdio.h>
+
#include "driver.h"
+#include "backend.h"
#include "random.h"
/* Period parameters */
@@ -236,20 +239,63 @@
/*-------------------------------------------------------------------------*/
void
-seed_random (uint32 seed)
+seed_random_from_int (uint32 seed)
/* Initialize the generator */
{
+ printf("%s Seeding PRG with: 0x%lx\n"
+ , time_stamp(), (unsigned long)seed);
+ debug_message("%s Seeding PRG with: 0x%lx\n"
+ , time_stamp(), (unsigned long)seed);
+
unsigned long init[4];
init[0] = seed & 0xFFF;
init[1] = (seed >>= 8) & 0xFFF;
init[2] = (seed >>= 8) & 0xFFF;
init[3] = (seed >>= 8) & 0xFFF;
init_by_array(init, 4);
-} /* seed_random() */
+} /* seed_random_from_int() */
/*-------------------------------------------------------------------------*/
+
+void
+seed_random(ph_uint mode)
+ /* Depending on mode seed the generator with an array of 624 p_int from
+ * /dev/urandom, /dev/random or use the current driver time (the latter
+ * ist also used as fall-back)
+ */
+{
+ FILE *seedsrc = NULL; // Filepointer
+
+ if (mode==PRG_SEED_RANDOM) {
+ seedsrc = fopen("/dev/random","rb");
+ }
+ else if (mode==PRG_SEED_URANDOM) {
+ seedsrc = fopen("/dev/urandom","rb");
+ }
+ // try getting 624 32-bit values from /dev/(u)random
+ if (seedsrc) {
+ uint32 seeddata[N];
+ ph_uint count = fread( seeddata, sizeof(uint32), N, seedsrc );
+ fclose(seedsrc);
+ if( count == N ) {
+ init_by_array( seeddata, N ); // seed PRG
+ printf("%s Seeding PRG from %s.\n", time_stamp(),
+ (mode==PRG_SEED_RANDOM?"/dev/random":"/dev/urandom"));
+ debug_message("%s Seeding PRG from %s.\n", time_stamp(),
+ (mode==PRG_SEED_RANDOM?"/dev/random":"/dev/urandom"));
+ return;
+ } // if (count == N)
+ } // if (seedsrc)
+ // Fall-back: driver clock
+ printf("%s Seeding PRG with current driver time\n"
+ , time_stamp());
+ debug_message("%s Seeding PRG with current driver time\n"
+ , time_stamp());
+ seed_random_from_int((uint32)current_time);
+} /* seed_random_from_int() */
+
uint32
random_number (uint32 n)
--- ldmud-3.3.714.orig/doc/driver/invocation 2006-07-10 04:40:33.000000000 +0200
+++ ldmud-3.3.714/doc/driver/invocation 2007-09-14 21:31:17.000000000 +0200
@@ -245,7 +245,15 @@
--y|--yydebug
Enable debugging of the LPC compiler.
Only available if compiled with YYDEBUG.
-
+
+ --randominit
+ Chooses the source of the seed for the random number generator.
+ Possible values are: 0 (system clock, default), 1 (/dev/random)
+ and 2 (/dev/urandom).
+ Option 1 and 2 prevent guessing of the PRG seed, 2 is recommended
+ because /dev/urandom doesn't block upon read.
+ (Note: the last one of --randominit and --random-seed wins!)
+
--random-seed <num>
Seed value for the random number generator. If not given, the
driver chooses a seed value on its own.
@@ -333,3 +341,4 @@
LDMud 3.3.475/3.2.11 added --tls-key, --tls-cert.
LDMud 3.3.672/3.2.11 added --tls-trustfile, --tls-trustdirectory.
LDMud 3.3.677 added --max-mapping-keys.
+ LDMud 3.3.x added --randominit.
| ||||
|
|
Ok, my suggested patch does the following: - rename random_seed(uint32) to random_seed_from_int(uint32) - introduce random_seed(ph_uint mode): Seeds the PRG from current_time (mode==0), from /dev/random (mode==1) or from /dev/urandom (mode==2). If /dev/(u)random doesn't supply the 624 uint32 values, current_time will be used as fallback. - move debug messages concerning the seeding of the PRG from main.c to random.c (seed_random_from_int() and seed_random()). - removes now unneeded static uint32 random_seed from main.c - add command-line option --randominit which takes 0|1|2. - adds --randominit to doc/driver/invocation The default behaviour of the driver should not be changed by this, /dev/(u)random will only be used if specified at command-line. --random-seed is also usable as before. BTW: The last one of --randominit or -random-seed in the arguments wins. |
|
|
Combined patch with SFMT (0000527) committed as r2470. |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2007-09-14 02:37 | zesstra | New Issue | |
| 2007-09-14 13:37 | zesstra | Note Added: 0000541 | |
| 2007-09-14 13:38 | zesstra | File Added: randomseed.diff | |
| 2008-06-30 02:57 | zesstra | Status | new => assigned |
| 2008-06-30 02:57 | zesstra | Assigned To | => zesstra |
| 2008-07-02 06:17 | zesstra | Relationship added | related to 0000527 |
| 2009-01-04 13:34 | zesstra | Note Added: 0000848 | |
| 2009-01-04 13:34 | zesstra | Status | assigned => resolved |
| 2009-01-04 13:34 | zesstra | Fixed in Version | => 3.3.718 |
| 2009-01-04 13:34 | zesstra | Resolution | open => fixed |