CPAN::Reporter, Transport::Metabase, and libwww-lwp 6

Recently libwww-lwp-6.00 hit the CPAN with one major change in the default operating behavior: connecting using the https protocol would cause the certificate chain from the server to be verified that it was issued by a trusted certificate authority. In my opinion this behavior is a good thing, as this finally brings libwww-lwp in line with all the browsers.

There were a few blog articles where this change caught people by surprise in that submissions to the CPAN Testers Metabase failed (due to metabase.cpantesters.org using a self-signed certificate). Because metabase.cpantesters.org uses a self-signed certificate, simply installing Mozilla::CA, which is a bundle of all the trusted CAs by Mozilla, will not correct the submissions failures (plus you have to install a few other modules). The typically error you will see once you have libwww-perl-6.00 install is as follows:

CPAN::Reporter: Test::Reporter: error from 'Test::Reporter::Transport::Metabase:'
fact submission failed: Can't connect to metabase.cpantesters.org:443 (certificate verify failed) at C:\strawberry\perl\site\lib/Metabase/Client/Simple.pm line 111

You may also see the following error if you do not have IO::Socket::SSL installed:

CPAN::Reporter: Test::Reporter: error from 'Test::Reporter::Transport::Metabase:'
fact submission failed: Can't connect to metabase.cpantesters.org:443 (Crypt-SSLeay can't verify hostnames) at C:\strawberry\perl\site\lib/Metabase/Client/Simple.pm line 111

As a work-around for this problem (without just disabling certificate checking or other environment changes) I wrote two classes that subclass Metabase::Client::Simple and Test::Reporter::Transport::Metabase that make them specific to submitting to the CPAN Testers Metabase and bundle the metabase.cpantesters.org certificate and check the certificate against the bundled one. Having a module where a certificate is bundled may or may not be what CPAN Testers Metabase wants, which is why I do not have any intentions on actually publishing this distribution. If you are interested in looking at it, you can view it as Github Gist 867743 (using the download button at the top results in the distribution tarball).

The premise is to subclass the Metabase transport to set the uri to be the CPAN Testers Metabase URI by default and to set the client to my client subclass. The client subclass simply wraps the LWP::UserAgent generation method and sets the SSL option to verify the certificate with the bundled certificate. This accomplished by this excerpt:

around _ua => sub {
    my $orig = shift;
    my $self = shift;
 
    my $ua_was_generated = !$self->{_ua};
 
    # Get the standard generated UA
    my $ua = $self->$orig(@_);
 
    if ($ua_was_generated) {
        # Add our SSL options to the UA
        $ua->ssl_opts(SSL_ca_file => File::ShareDir::dist_file('Test-Reporter-Transport-Metabase-CPANTesters', 'metabase.cpantesters.org.crt'));
    }
 
    return $ua;
};

If you are interested in using the module, you can download the tarball and run the commands outlined in INSTALL and be sure to change your CPAN Reporter configuration as noted in README to actually use the new module. After you install it, you can simply set your CPAN Reporter configuration file to have:

transport = Metabase::CPANTesters id_file ~/.cpanreporter/metabase_id.json

A possible solution to this situation may be for the Test::Reporter::Transport::Metabase to have an option for SSL parameters like the certificate file and pass that parameter on to Metabase::Client::Simple for it to set in it’s LWP::UserAgent instance (or metabase.cpantesters.org could have a certificate signed by a CA trusted by Mozilla, though this solution may cost money for the certificate purchase).

One Comment

  1. [...] an update to my previous post, David Golden has posted an update that the certificate for metabase.cpantesters.org is now signed [...]

Leave a Reply