#!/usr/bin/perl

# reseed - re-seed the random number generator using a number
# acquired from random.org, the Internet random numbers source
# Generally this script is intended to be run as part of the
# boot process, and must be run with root permissions
# $Id: reseed,v 1.1 1999/11/01 12:30:43 dobsons Exp $

use strict;

use LWP::UserAgent;
use URI::URL;
use Net::Ping;

autoflush STDOUT 1;
print "Re-seeding random number generator from net...";

my $proxies = "/etc/sysconfig/proxies";
my $random_device = "/dev/urandom";
my $bytes = 512;
my $random_host = "www.random.org";
my $random_url =
"http://$random_host/cgi-bin/randnum?num=$bytes&min=0&max=255&col=1";
my $ping_host = $random_host;

# set up web access from local sysconfig
my $ua = new LWP::UserAgent;
my ($lower, $url);
if(-f $proxies)
  {
    # We expect $proxies to contain a file of shell variable definitions
    # for proxies for different protocols - in particular a variable
    # HTTP_PROXY for the local web proxy. Otherwise we assume a direct
    # Internet connection
    open(PROXY, "<$proxies") || die("can't open $proxies\n");
    while(<PROXY>)
      {
        if(/(\w+)_PROXY \s* = \s* \"([^\"]*)\"/ix)
          {
            $lower = $1;   $url = $2;
            $lower =~ tr/A-Z/a-z/;
            $ua->proxy([$lower], $url);
            if($url =~ m#\w+://([^/:]+)#)
               { $ping_host = $1; }
          }
      }
    close(PROXY);
  }

# see if we've got net access
my $p = new Net::Ping('icmp');
die("no net access\n") unless $p->ping($ping_host);
$p->close();

# hit random number source for a seed
my ($request, $response, @bytes);
$request = new HTTP::Request("GET", $random_url);
$response = $ua->request($request);

# generate a byte stream from the numbers
@bytes = split /\n/, $response->content();
map { chr($_) } @bytes;

# write the byte stream into the random number generator
open(RANDOM, "| dd of=$random_device bs=$bytes count=1 2>/dev/null") ||
die("can't write to $random_device\n");
print RANDOM (join "", @bytes);
close(RANDOM);

print "done\n";
exit 0;
