Skip to content
Snippets Groups Projects
Commit 6d00f059 authored by Niels Möller's avatar Niels Möller
Browse files

*** empty log message ***

Rev: lib/modules/ADT.pmod/queue.pike:1.1
Rev: lib/modules/ADT.pmod/struct.pike:1.1
Rev: lib/modules/Crypto/randomness.pmod.pike:1.1
parent 127989fc
No related branches found
No related tags found
No related merge requests found
/* queue.pike
*
* A FIFO queue. Used by connection*
*/
#define QUEUE_SIZE 100
array l;
int head;
int tail;
void create()
{
l = allocate(QUEUE_SIZE);
head = tail = 0;
}
void put(mixed item)
{
if (head == sizeof(l))
{
l = l[tail ..];
head -= tail;
tail = 0;
l += allocate(sizeof(l) + QUEUE_SIZE);
}
l[head++] = item;
// werror(sprintf("Queue->put: %O\n", l[tail..head-1]));
}
mixed get()
{
// werror(sprintf("Queue->get: %O\n", l[tail..head-1]));
mixed res;
if (tail == head)
return 0;
res = l[tail];
l[tail++] = 0;
return res;
}
mixed peek()
{
return (tail < head) && l[tail];
}
void flush()
{
create();
}
/* struct.pike
*
* Read and write structures from strings.
*/
string buffer;
int index;
void create(void|string s)
{
buffer = s || "";
index = 0;
}
void add_data(string s)
{
buffer += s;
}
string pop_data()
{
string res = buffer;
create();
return res;
}
void put_int(int i, int len)
{
add_data(sprintf("%*c", len, i));
}
void put_var_string(string s, int len)
{
put_int(strlen(s), len);
add_data(s);
}
void put_fix_string(string s)
{
add_data(s);
}
void put_fix_array(array(int) data, int item_size)
{
foreach(data, int i)
put_int(i, item_size);
}
void put_var_array(array(int) data, int item_size, int len)
{
put_int(sizeof(data), len);
put_fix_array(data, item_size);
}
mixed get_int(int len)
{
mixed i;
if ( (strlen(buffer) - index) < len)
throw( ({ "SSL.struct->get_int: no data\n", backtrace() }) );
if (len <= 3)
{
sscanf(buffer, "%*" + (string) index +"s%" + (string) len + "c", i);
}
else
i = Gmp.mpz(buffer[index .. index+len-1], 256);
index += len;
return i;
}
string get_fix_string(int len)
{
string res;
if ((strlen(buffer) - index) < len)
throw( ({ "SSL.struct->get_fix_string: no data\n", backtrace() }) );
res = buffer[index .. index + len - 1];
index += len;
return res;
}
string get_var_string(int len)
{
return get_fix_string(get_int(len));
}
array(mixed) get_fix_array(int item_size, int size)
{
array(mixed) res = allocate(size);
for(int i = 0; i<size; i++)
res[i] = get_int(item_size);
return res;
}
array(mixed) get_var_array(int item_size, int len)
{
return get_fix_array(item_size, get_int(len));
}
int is_empty()
{
return (index == strlen(buffer));
}
#if 0
constant FIELD_int = 1;
constant FIELD_string = 2;
class field
{
string name; /* Name of field */
int type;
int len; /* For integers: length,
* for strings: index to the field that holds the length */
}
array(object(field)) description;
array(function) conversions;
class parser
{
string buffer = "";
object info;
int field; /* Field being read */
object o; /* The object to fill in */
object me;
mapping(int:function(string, object:void)) conversions;
create(object i)
{
info = i;
o = i->prog();
me = this_object();
}
object|string recv(string data)
{
buffer += data;
while(strlen(buffer) >= info->needed_chars[field])
{
object err;
if (err = info->conversions[field](me))
return err;
field++;
if (field >= sizeof(info->description))
return buffer[info->needed_chars[field-1]..];
}
return 0;
}
}
array compile()
{
conversions =
#endif
/* 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"
#define SYSTEM_COMMANDS "rup & ping -s 255.255.255.255 256 30 &" \
"uptime & ps -fel & vmstat -s & iostat -cdDItx &"
#define PRIVATE
PRIVATE object global_rc4;
PRIVATE string some_entropy()
{
object parent_pipe, child_pipe;
parent_pipe = Stdio.File();
child_pipe = parent_pipe->pipe();
if (!child_pipe)
throw( ({ "Crypto.random->popen: couldn't create pipe\n", backtrace() }) );
if (!fork())
{ /* Child */
catch {
object stderr = Stdio.File();
object stdin = Stdio.File();
destruct(parent_pipe);
stderr->open("/dev/null", "w");
stderr->dup2(Stdio.File("stderr"));
stdin->open("/dev/null", "r");
stdin->dup2(Stdio.File("stdin"));
child_pipe->dup2(Stdio.File("stdout"));
catch(exece("/bin/sh", ({ "-c", SYSTEM_COMMANDS }), ([ "PATH" : PATH ]) ));
};
exit(17);
} else {
/* Parent */
string res;
destruct(child_pipe);
res = parent_pipe->read(0x7fffffff);
return res;
}
}
class pike_random {
string read(int len)
{
return sprintf("%@c", Array.map(allocate(len), lambda(int dummy)
{
return random(256);
} ));
}
}
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)
{
return rc4::crypt(replace(allocate(len), 0, "\47") * "");
}
}
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)
{
object res;
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() }) );
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment