Crypt::Random::Source::Factory - Load and instantiate sources of random data


Crypt-Random-Source documentation Contained in the Crypt-Random-Source distribution.

Index


Code Index:

NAME

Top

Crypt::Random::Source::Factory - Load and instantiate sources of random data

SYNOPSIS

Top

    use Crypt::Random::Source::Factory;

    my $f = Crypt::Random::Source::Factory->new;

    my $strong = $f->get_strong;

    my $weak = $f->get_weak;

    my $any = $f->get;

DESCRIPTION

Top

This class implements a loading and instantiation factory for Crypt::Random::Source objects.

If $ENV{CRYPT_RANDOM_NOT_PLUGGABLE} is set then only a preset list of sources will be tried. Otherwise Module::Find will be used to locate any installed sources, and use the first available one.

METHODS

Top

get %args

Instantiate any random source, passing %args to the constructor.

The type argument can be weak, strong or any.

get_weak %args

get_strong %args

Instantiate a new weak or strong random source.

AUTHOR

Top

  Yuval Kogman <nothingmuch@woobling.org>

COPYRIGHT AND LICENSE

Top


Crypt-Random-Source documentation Contained in the Crypt-Random-Source distribution.

package Crypt::Random::Source::Factory;
BEGIN {
  $Crypt::Random::Source::Factory::AUTHORITY = 'cpan:NUFFIN';
}
BEGIN {
  $Crypt::Random::Source::Factory::VERSION = '0.07';
}
# ABSTRACT: Load and instantiate sources of random data

use Any::Moose;

use Carp qw(croak);

use Module::Find;

use namespace::clean -except => [qw(meta)];

sub get {
    my ( $self, %args ) = @_;

    my $type = delete $args{type} || "any";

    my $method = "new_$type";

    $self->can($method) or croak "Don't know how to create a source of type $type";

    $self->$method(%args);
}

sub get_weak {
    my ( $self, @args ) = @_;
    $self->get( @args, type => "weak" );
}

sub get_strong {
    my ( $self, @args ) = @_;
    $self->get( @args, type => "strong" );
}

has weak_source => (
    isa => "ClassName",
    is  => "rw",
    lazy_build => 1,
    clearer    => "clear_weak_source",
    handles    => { new_weak => "new" },
);

sub _build_weak_source {
    my $self = shift;
    $self->best_available(@{ $self->weak_sources });
}

has strong_source => (
    isa => "ClassName",
    is  => "rw",
    lazy_build => 1,
    clearer    => "clear_strong_source",
    handles    => { new_strong => "new" },
);

sub _build_strong_source {
    my $self = shift;
    $self->best_available(@{ $self->strong_sources });
}

has any_source => (
    isa => "ClassName",
    is  => "rw",
    lazy_build => 1,
    clearer    => "clear_any_source",
    handles    => { new_any => 'new' },
);

sub _build_any_source {
    my $self = shift;
    $self->weak_source || $self->strong_source;
}

has scan_inc => (
    is  => "ro",
    isa => "Bool",
    lazy_build => 1,
);

sub _build_scan_inc {
    my $self = shift;

    if ( exists $ENV{CRYPT_RANDOM_NOT_PLUGGABLE} ) {
        return !$ENV{CRYPT_RANDOM_NOT_PLUGGABLE};
    } else {
        return 1;
    }
}

has weak_sources => (
    isa => "ArrayRef[Str]",
    is  => "rw",
    lazy_build => 1,
);

sub _build_weak_sources {
    my $self = shift;

    if ( $self->scan_inc ) {
        $self->locate_sources("Weak");
    } else {
        return [qw(
            Crypt::Random::Source::Weak::devurandom
            Crypt::Random::Source::Weak::openssl
            Crypt::Random::Source::Weak::rand
        )];
    }
}

has strong_sources => (
    isa => "ArrayRef[Str]",
    is  => "rw",
    lazy_build => 1,
);

sub _build_strong_sources {
    my $self = shift;

    if ( $self->scan_inc ) {
        return $self->locate_sources("Strong");
    } else {
        return [qw(
            Crypt::Random::Source::Strong::devrandom
            Crypt::Random::Source::Strong::egd
        )];
    }
}

sub best_available {
    my ( $self, @sources ) = @_;

    my @available = grep { local $@; eval { Any::Moose::load_class($_); $_->available }; } @sources;

    my @sorted = sort { $b->rank <=> $a->rank } @available;

    wantarray ? @sorted : $sorted[0];
}

sub first_available {
    my ( $self, @sources ) = @_;

    foreach my $class ( @sources ) {
        local $@;
        return $class if eval { Any::Moose::load_class($class); $class->available };
    }
}

sub locate_sources {
    my ( $self, $category ) = @_;
    my @sources = findsubmod "Crypt::Random::Source::$category";
    # Untaint class names (which are tainted in taint mode because
    # they came from the disk).
    ($_) = $_ =~ /^(.*)$/ foreach @sources;
    return \@sources;
}

1;


# ex: set sw=4 et:

__END__