Apache2-API

 view release on metacpan or  search on metacpan

SIGNATURE  view on Meta::CPAN

This file contains message digests of all files listed in MANIFEST,
signed via the Module::Signature module, version 0.88.

To verify the content in this distribution, first make sure you have
Module::Signature installed, then type:

    % cpansign -v

It will check each file's integrity, as well as the signature's
validity.  If "==> Signature verified OK! <==" is not displayed,
the distribution may already have been compromised, and you should
not run its Makefile.PL or Build.PL.

-----BEGIN PGP SIGNED MESSAGE-----

lib/Apache2/API/Password.pod  view on Meta::CPAN

=encoding utf8

=head1 NAME

Apache2::API::Password - Create and verify HTTP Basic Auth password hashes (APR1/bcrypt/SHA-crypt)

=head1 SYNOPSIS

	use Apache2::API::Password;
    # Create a new hash from a cleartext password (random salt)
    # MD5-crypt (APR1, "$apr1$") - default
    my $ht = Apache2::API::Password->new( 'secret', create => 1 );
    my $hash = $ht->hash; # "$apr1$abcd1234$...."

    # Create APR1 with a provided salt (max 8 chars; [./0-9A-Za-z])
    my $ht2 = Apache2::API::Password->new( 'secret', create => 1, salt => 'hfT7jp2q' );
    say $ht2->hash;

    # Wrap an existing APR1 ($apr1$) hash and verify user input
    my $ht3 = Apache2::API::Password->new( '$apr1$hfT7jp2q$DcU1Hf5w2Q/9G8yqv1hbl.' );
    my $ok  = $ht3->matches( 'secret' );

    # Bcrypt ($2y$), choose a cost (04..31); defaults to 12
    my $b  = Apache2::API::Password->new('s3cret', create => 1, algo => 'bcrypt', bcrypt_cost => 12);
    say $b->hash; # "$2y$12$..."

    # SHA-crypt ($5$ = SHA-256, $6$ = SHA-512), optionally set rounds
    my $s6 = Apache2::API::Password->new('s3cret', create => 1, algo => 'sha512', sha_rounds => 150000);
    say $s6->hash; # "$6$rounds=150000$..."

lib/Apache2/API/Password.pod  view on Meta::CPAN

=back

All 64 encoding symbols (including trailing C<.> or C</>) are valid.

=head1 SECURITY NOTES

=over 4

=item * Empty passwords

All algorithms accept empty strings. An empty password will verify successfully if you store its hash. Avoid this in production.

=item * Legacy algorithm

APR1/MD5-crypt is legacy and weak by modern standards. Prefer C<bcrypt> (with a cost appropriate to your CPU budget) or C<sha512> (SHA-crypt) where bcrypt is not available; retain C<APR1> only for Apache compatibility. For bcrypt, remember the 72-byt...

=item * Salt generation

Salt generation requires either L<Crypt::URandom> or L<Bytes::Random::Secure> to be installed. If neither is available, C<make>, C<make_md5>, C<make_bcrypt>, C<make_sha256>, and C<make_sha512> will return an error. The use of the non-cryptographic C<...

=back

t/01.api.t  view on Meta::CPAN

                Accept_Encoding => 'gzip, deflate, br',
                Accept_Language => 'en-GB,fr-FR;q=0.8,fr;q=0.6,ja;q=0.4,en;q=0.2',
            ),
            keep_alive      => 1,
        );
        Apache::TestRequest::user_agent( @ua_args, reset => 1 );
        $ua = Apache::TestRequest->new( @ua_args );
        # To get the fingerprint for the certificate in ./t/server.crt, do:
        # echo "sha1\$$(openssl x509 -noout -in ./t/server.crt -fingerprint -sha1|perl -pE 's/^.*Fingerprint=|(\w{2})(?:\:?|$)/$1/g')"
        $ua->ssl_opts(
            # SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, 
            # SSL_verify_mode => 0x00
            # verify_hostname => 0,
            SSL_fingerprint => 'sha1$DEE8650E44870896E821AAE4A5A24382174D100E',
            # SSL_version     => 'SSLv3',
            # SSL_verfifycn_name => 'localhost',
        );
    }
    $proto = HAS_SSL ? 'https' : 'http';
    diag( "Host: '$host', port '$port'" ) if( $DEBUG );
};

use strict;

t/06.apr1.t  view on Meta::CPAN

    # use_ok( 'Apache2::API' ) || BAIL_OUT( 'Unable to load Apache2::API' );
    use ok( 'Apache2::API' ) || BAIL_OUT( 'Unable to load Apache2::API' );
};

use strict;
use warnings;

# my $api = Apache2::API->new( debug => $DEBUG );
my $api = Apache2::API->new;

sub verify_apr1
{
    my( $passwd, $hash ) = @_;
    return(0) unless( defined( $passwd ) && defined( $hash ) );
    return(0) unless( $hash =~ m!\A\$apr1\$([./0-9A-Za-z]{1,8})\$([./0-9A-Za-z]{22})\z! );
    my( $salt, $body ) = ( $1, $2 );
    my $calc = apr1_md5( $passwd, $salt );
    return( $hash eq $calc );
}

sub _have_module

t/06.apr1.t  view on Meta::CPAN

};

subtest 'determinism for fixed salt' => sub
{
    my $h1 = apr1_md5( 'secret', 'hfT7jp2q' );
    my $h2 = apr1_md5( 'secret', 'hfT7jp2q' );
    is( $h1, $h2, 'same password+salt => same hash' );
    like( $h1, qr/\A\$apr1\$hfT7jp2q\$[.\/0-9A-Za-z]{22}\z/, 'hash contains given salt' );
};

subtest 'verify positive/negative' => sub
{
    my $h = apr1_md5( 'opensesame', 'AB12.Cd/' );
    ok( verify_apr1( 'opensesame', $h ), 'verify succeeds on correct password' );
    ok( !verify_apr1( 'wrong',     $h ), 'verify fails on wrong password' );

    ok( !verify_apr1( 'opensesame', '$apr1$bad*salt$xxxxxxxxxxxxxxxxxxxxxx' ), 'rejects invalid salt chars' );
    ok( !verify_apr1( 'opensesame', '$apr1$short$too_short' ),                 'rejects invalid body length' );
};

subtest 'random salt uniqueness' => sub
{
    my %seen;
    my $collisions = 0;
    for( 1..50 )
    {
        # random salt
        my $h = apr1_md5( 'samepass' );

t/06.apr1.t  view on Meta::CPAN


    SKIP:
    {
        skip( 'Crypt::PasswdMD5 not installed', scalar( @cases ) ) unless( $HAVE_REF );
        for my $c ( @cases )
        {
            my( $pw, $salt ) = @$c;
            my $mine = apr1_md5( $pw, $salt );
            my $ref  = Crypt::PasswdMD5::apache_md5_crypt( $pw, $salt );
            is( $mine, $ref, "matches reference for pw=[${pw}] salt=[$salt]" );
            ok( verify_apr1( $pw, $mine ), 'verify_apr1 accepts our own output' );
        }
    };
};

subtest 'bcrypt make + matches' => sub
{
    my $have_any = $have_bcrypt_crypt || $have_bcrypt_fallback;
    SKIP:
    {
        unless( $have_any )

t/06.apr1.t  view on Meta::CPAN


        my $pw = "correct horse battery staple";
        my $ht = $api->htpasswd( $pw, create => 1, algo => 'bcrypt', bcrypt_cost => $bcrypt_cost );
        ok( $ht, 'constructed bcrypt object' );

        my $hash = $ht->hash;
        like( $hash, qr/^\$2[aby]\$\d{2}\$[A-Za-z0-9.\/]{22}[A-Za-z0-9.\/]{31}\z/, 'bcrypt hash format' );

        ok( $ht->matches( $pw ), 'matches() true for bcrypt' );

        # Re-wrap existing hash and verify again
        my $ht2 = $api->htpasswd( $hash );
        ok( $ht2->matches( $pw ), 're-wrapped bcrypt hash verifies' );
    };
};

subtest 'sha256 ($5$) make + matches' => sub
{
    my $have_any = $have_sha256_crypt || $have_sha_fallback;
    SKIP:
    {

t/92.signature.t  view on Meta::CPAN

#!/usr/bin/perl

use Test2::V0;
# use Test2::Tools::Basic;

if (!$ENV{AUTHOR_TESTING}) {
    skip_all( "Set the environment variable AUTHOR_TESTING to enable this test." );
}
elsif (!eval { require Module::Signature; 1 }) {
    skip_all( "Next time around, consider installing Module::Signature, ".
      "so you can verify the integrity of this distribution." );
}
elsif ( !-e 'SIGNATURE' ) 
{
    skip_all( "SIGNATURE not found" );
}
elsif ( -s 'SIGNATURE' == 0 ) {
    skip_all( "SIGNATURE file empty" );
}
elsif (!eval { require Socket; Socket::inet_aton('keyserver.ubuntu.com') }) {
    skip_all( "Cannot connect to the keyserver to check module signature" );
}
else {
    plan tests => 1;
}

my $ret = Module::Signature::verify();
SKIP: {
    skip "Module::Signature cannot verify", 1 
      if $ret eq Module::Signature::CANNOT_VERIFY();

    cmp_ok $ret, '==', Module::Signature::SIGNATURE_OK(), "Valid signature";
}

done_testing();

__END__

t/lib/Test/Apache2/API.pm  view on Meta::CPAN

    use HTTP::Request;

    my $hostport = Apache::TestRequest::hostport( $config ) || '';
    my( $host, $port ) = split( ':', ( $hostport ) );
    my $mp_host = 'www.example.org';
    Apache::TestRequest::user_agent(reset => 1, keep_alive => 1 );
    my $ua = Apache::TestRequest->new;
    # To get the fingerprint for the certificate in ./t/server.crt, do:
    # echo "sha1\$$(openssl x509 -noout -in ./t/server.crt -fingerprint -sha1|perl -pE 's/^.*Fingerprint=|(\w{2})(?:\:?|$)/$1/g')"
    $ua->ssl_opts(
        # SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, 
        # SSL_verify_mode => 0x00
        # verify_hostname => 0,
        SSL_fingerprint => 'sha1$DEE8650E44870896E821AAE4A5A24382174D100E',
        # SSL_version     => 'SSLv3',
        # SSL_verfifycn_name => 'localhost',
    );
    my $req = HTTP::Request->new( 'GET' => "${proto}://${hostport}/tests/api/some_method" );
    my $resp = $ua->request( $req );
    is( $resp->code, Apache2::Const::HTTP_OK, 'some test name' );

=head1 VERSION

t/lib/Test/Apache2/API/Request.pm  view on Meta::CPAN

=head1 SYNOPSIS

    my $hostport = Apache::TestRequest::hostport( $config ) || '';
    my( $host, $port ) = split( ':', ( $hostport ) );
    my $mp_host = 'www.example.org';
    Apache::TestRequest::user_agent(reset => 1, keep_alive => 1 );
    my $ua = Apache::TestRequest->new;
    # To get the fingerprint for the certificate in ./t/server.crt, do:
    # echo "sha1\$$(openssl x509 -noout -in ./t/server.crt -fingerprint -sha1|perl -pE 's/^.*Fingerprint=|(\w{2})(?:\:?|$)/$1/g')"
    $ua->ssl_opts(
        # SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, 
        # SSL_verify_mode => 0x00
        # verify_hostname => 0,
        SSL_fingerprint => 'sha1$DEE8650E44870896E821AAE4A5A24382174D100E',
        # SSL_version     => 'SSLv3',
        # SSL_verfifycn_name => 'localhost',
    );
    my $req = HTTP::Request->new( 'GET' => "${proto}://${hostport}/tests/request/some_method" );
    my $resp = $ua->request( $req );
    is( $resp->code, Apache2::Const::HTTP_OK, 'some test name' );

=head1 VERSION

t/lib/Test/Apache2/API/Response.pm  view on Meta::CPAN

=head1 SYNOPSIS

    my $hostport = Apache::TestRequest::hostport( $config ) || '';
    my( $host, $port ) = split( ':', ( $hostport ) );
    my $mp_host = 'www.example.org';
    Apache::TestRequest::user_agent(reset => 1, keep_alive => 1 );
    my $ua = Apache::TestRequest->new;
    # To get the fingerprint for the certificate in ./t/server.crt, do:
    # echo "sha1\$$(openssl x509 -noout -in ./t/server.crt -fingerprint -sha1|perl -pE 's/^.*Fingerprint=|(\w{2})(?:\:?|$)/$1/g')"
    $ua->ssl_opts(
        # SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, 
        # SSL_verify_mode => 0x00
        # verify_hostname => 0,
        SSL_fingerprint => 'sha1$DEE8650E44870896E821AAE4A5A24382174D100E',
        # SSL_version     => 'SSLv3',
        # SSL_verfifycn_name => 'localhost',
    );
    my $req = HTTP::Request->new( 'GET' => "${proto}://${hostport}/tests/response/some_method" );
    my $resp = $ua->request( $req );
    is( $resp->code, Apache2::Const::HTTP_OK, 'some test name' );

=head1 VERSION



( run in 0.788 second using v1.01-cache-2.11-cpan-39bf76dae61 )