6d00f01997-03-15Niels Möller /* randomness.pmod * * Assorted stronger or weaker randomnumber generators. */ /* These devices tries to collect entropy from the environment. * They differ in behaviour when they run low on entropy, /dev/random * will block if it can't provide enough random bits, while /dev/urandom * will degenerate into a reasonably strong pseudo random generator */ #define RANDOM_DEVICE "/dev/random" #define PRANDOM_DEVICE "/dev/urandom" /* Collect somewhat random data from the environment. Unfortunately, * this is quite system dependent */ #define PATH "/usr/sbin:/usr/etc:/usr/bin/:/sbin/:/etc:/bin"
ddab201998-01-19Fredrik Hübinette (Hubbe)  #ifndef __NT__
83aaef1998-01-21Henrik Grubbström (Grubba) #define SYSTEM_COMMANDS ({ "last -256", "arp -a", \
ddab201998-01-19Fredrik Hübinette (Hubbe)  "netstat -anv","netstat -mv","netstat -sv", \ "uptime","ps -fel","ps aux", \ "vmstat -s","vmstat -M", \ "iostat","iostat -cdDItx"}) #else #define SYSTEM_COMMANDS ({ "mem /c", "arp -a", "vol", "dir", "net view", \ "net statistics workstation","net statistics server", "net view" \ "net user" }) #endif
6d00f01997-03-15Niels Möller  #define PRIVATE PRIVATE object global_rc4; PRIVATE string some_entropy() {
ddab201998-01-19Fredrik Hübinette (Hubbe)  string res;
6d00f01997-03-15Niels Möller  object parent_pipe, child_pipe;
c3f7751998-02-06Fredrik Hübinette (Hubbe)  mapping env=getenv()+([]);
6d00f01997-03-15Niels Möller  parent_pipe = Stdio.File(); child_pipe = parent_pipe->pipe(); if (!child_pipe) throw( ({ "Crypto.random->popen: couldn't create pipe\n", backtrace() }) );
ddab201998-01-19Fredrik Hübinette (Hubbe)  #ifndef __NT__ object null=Stdio.File("/dev/null","rw"); env["PATH"]=PATH; #else object null=Stdio.File("nul:","rw"); #endif foreach(SYSTEM_COMMANDS, string cmd) { catch { Process.create_process(Process.split_quoted_string(cmd),
c029131998-02-06Fredrik Hübinette (Hubbe)  (["stdin":null, "stdout":child_pipe, "stderr":null, "env":env]));
ddab201998-01-19Fredrik Hübinette (Hubbe)  }; } destruct(child_pipe); return parent_pipe->read();
6d00f01997-03-15Niels Möller }
ddab201998-01-19Fredrik Hübinette (Hubbe) 
6d00f01997-03-15Niels Möller class pike_random { string read(int len) {
8177c41999-06-16David Hedbor  if (len > 16384) return read(len/2)+read(len-len/2); return (string)allocate(len, random)(256);
6d00f01997-03-15Niels Möller  } } class rc4_random { inherit Crypto.rc4 : rc4; void create(string secret) { object hash = Crypto.sha(); hash->update(secret); rc4::set_encrypt_key(hash->digest()); } string read(int len) {
0c8b101999-06-17Henrik Grubbström (Grubba)  if (len > 16384) return read(len/2)+read(len-len/2); return rc4::crypt("\47" * len);
6d00f01997-03-15Niels Möller  } } object reasonably_random() { if (file_stat(PRANDOM_DEVICE)) { object res = Stdio.File(); if (res->open(PRANDOM_DEVICE, "r")) return res; } if (global_rc4) return global_rc4; string seed = some_entropy(); if (strlen(seed) > 2000) return (global_rc4 = rc4_random(sprintf("%4c%O%s", time(), _memory_usage(), seed))); throw( ({ "Crypto.randomness.reasonably_random: No source found\n", backtrace() }) ); } object really_random(int|void may_block) {
e106c71997-04-10Niels Möller  object res = Stdio.File();
6d00f01997-03-15Niels Möller  if (may_block && file_stat(RANDOM_DEVICE)) { if (res->open(RANDOM_DEVICE, "r")) return res; } if (file_stat(PRANDOM_DEVICE)) { if (res->open(PRANDOM_DEVICE, "r")) return res; } throw( ({ "Crypto.randomness.really_random: No source found\n", backtrace() }) ); }
ddab201998-01-19Fredrik Hübinette (Hubbe)