Undefined subroutine LWP::Protocol::https::Socket::can_read called - perl

I'm trying to script some interaction between a Linux box and an ESXi host, using the VMware Perl library (which appears to call a SOAP service on the ESXi host).
I am getting an error for which I can't find a solution: Undefined subroutine &LWP::Protocol::https::Socket::can_read called at /usr/local/share/perl5/LWP/Protocol/http.pm line 22
I am currently running Net-HTTP-6.03. I did try with Net-HTTP-6.05 but it makes the web-based calls very slow (and subsequent ones also eventually fail, instead with about 1.2MB of XML as the error message) -- which various forums suggest is only resolvable by reverting to 6.03 (via cpan install GAAS/Net-HTTP-6.03.tar.gz).
The crux of my code is as follows:
use VMware::VIRuntime;
my $context = {
options => ParseOptions(), # result of using GetOpts::Long to parse command-line
session => undef
};
$ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = "Net::SSL"; # Suppresses SSL_VERIFY_NONE
if ($context->{options}->{'ignore-ssl-errors'}) {
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; # Ignores certificate errors
}
## next line fails
$context->{session} = Vim::login(
service_url => $context->{options}->{url},
username => $context->{options}->{username},
password => $context->{options}->{password}
);
Is there something else I (can|need to) do to get this working?

I've got it. I needed to reinstall Bundle::LWP from an older version, not just Net-HTTP. Without it, I had LWP v6.05 trying to talk to Net-HTTP v6.03.
Once I realised that LWP == libwww-perl (yes, I'm that new), I found the overall package I needed:
cpan install GAAS/libwww-perl-6.03.tar.gz

Reproduced with LWP 6.05 and Net::HTTP 6.01, which is the cocktail that MacPorts installs at the time of this writing. Upgrading Net::HTTP to 6.06 (current) solved it:
sudo cpan Net::HTTP

Related

Why does LWP fail to connect with "500 SSL negotiation failed"?

My Perl script sends some information to a remote server.
Below is a portion of the code
#!/var/hvmail/libexec/perl
use strict;
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use constant HANDLER_URL => "https://www.website.com/handler.php";
$ENV{HTTPS_DEBUG} = 1;
my $ua = LWP::UserAgent->new;
# Some DB stuff, not applicable
my $row; # This is a DB row ($sth->fetchrow_hashref())
my $req = POST ''.HANDLER_URL, [ %$row ];
my $res = $ua->request($req);
$res->is_success is false with $res->status_line being
500 SSL negotiation failed
We are running CentOS 6.4, Perl 5.10.1, OpenSSL 1.0.1e-fips.
Update
Here's the full output:
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL3 alert read:fatal:handshake failure
SSL_connect:error in SSLv2/v3 read server hello A
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL3 alert read:fatal:handshake failure
SSL_connect:failed in SSLv3 read server hello A
SSL_connect:before/connect initialization
SSL_connect:SSLv2 write client hello A
SSL_connect:failed in SSLv2 read server hello A
Error: [ 500 SSL negotiation failed: ]
Requested Command Output
Can't locate Net/SSLeay.pm
Can't locate LWP/Protocol/https.pm
You seem to be relying on Crypt::SSLeay. You shouldn't. It's outdated and incomplete.
Install the latest LWP::Protocol::https which will upgrade your LWP and install the preferred SSL/TLS stack consisting of the IO::Socket::SSL and Net::SSLeay.
A web search shows there are CentOS6 repositories with RPM packages for LWP::Protocol::https.
The server has disabled SSLv3 support which means the negotiation fails.
Once you install the package, if you are still seeing the same error, make sure your script is not forcing the use of Crypt::SSLeay. That is, make sure none of the following appears anywhere in your script:
use Net::HTTPS;
$Net::HTTPS::SSL_SOCKET_CLASS = 'Net::SSL';
or
local $ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = 'Net::SSL';
or
use Net::SSL;
If you are still running into problems, make sure there is no PERL_NET_HTTPS_SSL_SOCKET_CLASS environment variable in the script's run time environment.
Also, try
$ /var/hvmail/libexec/perl -MNet::SSLeay -le 'print $Net::SSLeay::VERSION'
and
$ /var/hvmail/libexec/perl -MLWP::Protocol::https -le 'print $LWP::Protocol::https::VERSION`'
and report the output.
I suspect the issue is that the new packages were installed for the system's perl whereas it seems you may have a separate perl.
If that is the case, you should install each package individually using /var/hvmail/libexec/perl. For example:
$ curl -O https://cpan.metacpan.org/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.7043.tar.gz
$ tar xvf App-cpanminus-1.7043.tar.gz
$ cd App-cpanminus-1.7043
$ /var/hvmail/libexec/perl Makefile.PL
$ make install
Figure out where cpanm was installed. I am hoping /var/hvmail/libexec.
$ /var/hvmail/libexec/cpanm LWP::Protocol::https
See also Updating all outdated Perl modules, but that may be risky on a production. Still, installing App::cpanoutdated, and seeing how outdated your Perl modules are might be useful
Now, keep in mind that tinkering with a production install like this is risky. Make sure you have a way to undo changes in case something goes wrong.
Finally, note that OpenSSL 1.0.1 versions are no longer supported:
With regards to current and future releases the OpenSSL project has adopted the following policy:
Version 1.1.0 will be supported until 2018-08-31.
Version 1.0.2 will be supported until 2019-12-31 (LTS).
Version 1.0.1 is no longer supported.
Version 1.0.0 is no longer supported.
Version 0.9.8 is no longer supported.
There is no need for ''.HANDLER_URL. It looks ugly, and HANDLER_URL is fine
You don't explain what is in $row or what the POST call requires, but it looks like this
my $req = POST ''.HANDLER_URL, [ %$row ];
my $res = $ua->request($req);
should be
my $res = $ua->post(HANDLER_URL, $row);

Perl Invalid version format from Compat.pm

I'm trying to publish a module, and am running into a lot of weird errors, the latest of which is as follows:
C:\Shared\John\Perl\unifdef+.0.5.1>build disttest
Creating Makefile.PL
Invalid version format (non-numeric data) at C:/perl/lib/Module/Build/Compat.pm
line 134.
The code at the specified line is:
if ( my $minimum_perl = $requires->{perl} ) {
my $min_ver = version->new($minimum_perl)->numify;
print {$fh} "require $min_ver;\n";
}
so it looks like $minimum_perl is corrupted. I do have the line:
require 5.10.0;
In the code, but that should be OK according to the documentation I've read.
I tried upgrading various modules, and finally I tried a cpan upgrade, and upgraded my entire cpan, but I'm still getting the error. Can anyone tell me what I'm doing wrong? I am running perl 5.24.1
Ok, figured it out (sort of). I'm posting an answer, as I assume others will run into the same problem, and hopefully this will help them. My Build.PL script was a cut/paste/modify from an example on the web. I had the following:
use 5.010000; # NOT 5.8.8 - needed by CPAN testers
use Module::Build;
my $builder = Module::Build->new( module_name => 'code::unifdef+'
, license => 'perl'
, requires => { perl => '>= 5.10.0' } #hmm, this doesn't work...
, dist_version => '0.005.001'
, dist_author => 'John Ulvr <perldev#ulvr.com>'
, dist_abstract => 'processes conditional parts of makefiles, c/c++ and kconfig files'
, create_readme => 0
, create_makefile_pl => 'traditional'
);
$builder->create_build_script; #generate Build
The requires line was causing the problem. I'm not sure why though, as I've seen other similar examples on the web of the requires clause, so either everyone is wrong, or there's some sort of bug in in Compat.pm. Removing the requires line fixes the problem (I have requires in the .pl file itself, so it should catch out-of-date issues).

inet_pton is not a valid Socket macro

I am getting below error with perl package 5.10.
"inet_pton is not a valid Socket macro"
if (Socket::inet_pton (AF_INET6,$self->{'ip'}) )
{
$log->print("we hit here and ip=$self->{'ip'}");
$self->{'session'} = Net::SNMP->session(-hostname => $self->{'ip'},
-community => $self->{'community'},
-port => $self->{'port'},
-version => 'snmpv2c');
}
Can you pls let me know the root cause ?
Socket uses an autoloader. That's the message it produces when you try to call a sub that doesn't exist.
$ perl -MSocket -wE'my $x = Socket::some_name()'
some_name is not a valid Socket macro at -e line 1
In other words, the error message is synonymous with
Undefined subroutine &Socket::inet_pton called
You must have a version of Socket that predates the addition of the module's support for inet_pton. Therefore, the fix is simply to upgrade that module.
Your Perl is too old. As far as I can tell, inet_pton support wasn't added until 5.12. Installing a newer version of Socket from CPAN may help, but I wouldn't bet on it. Perl 5.10 came out in 2007, and the IPv6 support back then was much worse than it is today.

Undefined symbol in SSLeay.so: OpenSSL_add_all_algorithms

I'm trying to do a download of files from a remote host using LWP. Here is a simplified version of my code that reproduces the error:
#!/usr/local/bin/perl5.8 -w
use strict;
use LWP::UserAgent;
my $userAgent = LWP::UserAgent->new;
$userAgent->agent("p_o_c");
my $request = HTTP::Request->new(GET=>"https://ajax.googleapis.com/ajax/libs/prototype/1.7.2.0/prototype.js");
my $response = $userAgent->request($request);
When I run this code, I get the following:
[dev] /home/me > ./tmp/poc.pl
/usr/local/bin/perl5.8: symbol lookup error: /usr/local/ext/perl/5.8.0/lib/site_perl/i686-linux-thread-multi/auto/Crypt/SSLeay/SSLeay.so: undefined symbol: OpenSSL_add_all_algorithms
Also, as seen above, I'm running perl 5.8. I'm running RHEL 6.4 (Santiago).
I've tried downloading a file over http (not https) and that works.
Does anyone have any idea on how to get this https download to work? I'm open to other methods too besides LWP, but this seemed like the easiest way.
As Oesor mentioned, I am using (not by choice) a very old version of Perl. Using a newer version fixed the issue.

Perl LWP::UserAgent request does not return using http1.1 but working fine using http1.0!? Why?

I have a very simple script (on a SLES11 system) to send a http1.1 request to a server. This worked fine for a long time. Since a couple of days it stopped working. I have no idea why. After some investigation I found out forcing the script to use http1.0 it is working again. I have no idea why. And I want to know why it is not working in its default http1.1 mode.
I already enabled debugging as much as I know it (see code below). But I do not see anything - my script just hangs. There is no network activity. I neiter see that a socket will be openend (netstat -a), nor I see any incoming traffic form my client on the server. (A "telnet myserver myport" works fine.)
Can someone please help me how to track down this problem? How can I enable more debug to see where the real problem is?
#!/usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;
use HTTP::Request::Common;
use LWP::Debug qw(+);
use LWP::UserAgent;
# Workaround: forcing http1.0 instead of using http1.1, it works again!
use LWP::Protocol::https10 ();
LWP::Protocol::implementor('https', 'LWP::Protocol::https10');
# EO workaround
my $ua = LWP::UserAgent->new;
$ua->ssl_opts( verify_hostname => 0 );
my $response = $ua->request(
POST 'https://myuser:mypassword#myserver:8888/service/myservice',
Connection => 'close', # Edit: added, see comments below
Content_Type => 'text/xml',
Content => '... my content ...'
);
$ua->request() does not return! I need to kill/^C the script!
Edit: ok, no one seems to have an idea how to continue. So I startet debugging it using perl debugger.
LWP::UserAgent::post(/usr/lib/perl5/site_perl/5.10.0/LWP/UserAgent.pm:418):
418: return $self->request( HTTP::Request::Common::POST( #parameters ), #suff );
So I can see it is not returning from request().
Anyway, due to the fact that LWP::UserAgent calls HTTP::Request::Common I changed my example code above back to use HTTP::Request::Common to skip that step while debugging.
Ok... New result:
LWP::Protocol::implementor(/usr/lib/perl5/site_perl/5.10.0/Net/HTTPS.pm:26):
26: eval { require IO::Socket::SSL; };
Inside request() it hangs at IO::Socket::SSL. Means, this script it enough for further debug:
#!/usr/bin/perl
require IO::Socket::SSL;
This statement does not come back.
Further down, inside IO::Socket::SSL it hangs at:
IO::Socket::SSL::CODE(0x1274370)(/usr/lib/perl5/site_perl/5.10.0/IO/Socket/SSL.pm:92):
92: Net::SSLeay::SSLeay_add_ssl_algorithms();
Ahhhh! There is already a bugreport concerning this issue: Net-SSLeay hangs on Suse 11 P2 pointing to Bug #81575 that says:
I enountered this same issue on SLES 11 SP2, which has openssl-0.9.8j installed.
An upgrade to openssl-0.9.8r did resolve the problem. ...
The packages for 0.9.8r can be found in this repository:
http://download.opensuse.org/repositories/security:/fips/
Guess that's it!
There is already a bugreport concerning this issue: Net-SSLeay hangs on Suse 11 P2 pointing to Bug #81575 that says:
I enountered this same issue on SLES 11 SP2, which has openssl-0.9.8j installed. An upgrade to openssl-0.9.8r did resolve the problem. ... The packages for 0.9.8r can be found in this repository: http://download.opensuse.org/repositories/security:/fips/
Guess that's it!