2012-10-02 12 views
8

Sto eseguendo il porting di un'applicazione da PHP/cURL a Perl e LWP :: UserAgent. Devo fare una richiesta POST a un server web e fornire un certificato client e un file chiave. Il codice PHP che sto cercando di replicare è questo:Utilizzo di LWP con SSL e certificati client

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($ch, CURLOPT_SSLCERT, "/path/to/certificate.pem"); 
curl_setopt($ch, CURLOPT_SSLKEY, "/path/to/private.key"); 
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, "secretpassword"); 

Ed ecco il mio codice Perl:

my $ua = LWP::UserAgent->new(); 
$ua->ssl_opts(
    SSL_verify_mode => 0, 
    SSL_cert_file => '/path/to/certificate.pem', 
    SSL_key_file => "/path/to/private.key", 
    SSL_passwd_cb => sub { return "secretpassword"; } 
); 

il codice PHP si collega al server, ma il codice Perl non riesce con:

Errore di lettura SSL error: 14094410: Routine SSL: SSL3_READ_BYTES: errore di handshake di avviso sslv3

Non riesco a capire cosa mi sfugge.

+0

È il 'private.key' (PHP) e' private.pem' (Perl) un errore di battitura o una parte del porting? – amon

+2

Il passaggio di più argomenti a [ssl_opts] (https://metacpan.org/module/LWP::UserAgent#ATTRIBUTES) non è documentato. Per sicurezza, chiama ssl_opts più volte o passali nel costruttore. Penso che funzioni, ma sia al sicuro. Potresti anche [segnalarlo come bug/funzionalità mancante] (https://rt.cpan.org/Public/Bug/Report.html?Queue=libwww-perl). – Schwern

+0

Quello era solo un refuso quando oscuravo il mio codice. Dovrebbe essere private.key per entrambi. Grazie per aver notato ma non è questo il problema. Ancora bisogno di aiuto! :) – kent

risposta

2
sub send_command(){ 
     my $command = shift; 
     my $parser = XML::LibXML->new('1.0','utf-8'); 

     print color ("on_yellow"), "SEND: ", $command, color ("reset"), "\n"; 

     # Create a request 
     my $req = HTTP::Request->new(GET => $Gateway.$command); 

     # Pass request to the user agent and get a response back 
     my $res; 
     eval { 
       my $ua; 
       local $SIG{'__DIE__'}; 
       $ua = LWP::UserAgent->new(); # или 
       $ua->ssl_opts(#$key => $value 
        SSL_version   => 'SSLv3', 
        SSL_ca_file   => '/ca.pem', 
        #SSL_passwd_cb  => sub { return "xxxxx\n"; }, 
        SSL_cert_file  => '/test_test_cert.pem', 
        SSL_key_file  => '/test_privkey_nopassword.pem', 
       ); # ssl_opts => { verify_hostname => 0 } 
       $ua->agent("xxxxxx xxxx_tester.pl/0.1 "); 
       $res = $ua->request($req); 

     }; 
     warn [email protected] if [email protected]; 
     # Check the outcome of the response 
     if ($res->is_success) { 
       open xxxLOG, ">> $dir/XXXX_tester.log"; 
       my $without_lf = $res->content; 
       $without_lf =~ s/(\r|\n)//gm; 
       print PAYLOG $without_lf,"\n"; 
       close PAYLOG; 
     } 
     else { 
       return $res->status_line; 
     }  
     print color ("on_blue"), "RESPONSE: ", color ("reset"), respcode_color($res->content), color ("reset"),"\n\n"; 
     return $res->content; 
} 
3

La risposta di emazep in alto ha risolto il mio problema. Sto usando il codice Perl di esempio da UPS per collegarmi al loro servizio Rate via XML. Dai miei test, questo funzionerà ogni volta che LWP :: UserAgent viene chiamato senza argomenti che puoi controllare direttamente, il che lo rende utile se stai utilizzando qualche altro modulo che effettua chiamate a LWP per te. Basta usare Net :: SSL (in aggiunta a qualsiasi pacchetti hanno già utilizzato LWP) e impostare alcune variabili d'ambiente:

... 
use Net::SSL; 
$ENV{HTTPS_VERSION} = 3; 
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; 
my $browser = LWP::UserAgent->new(); 
... 

Questo è tutto! Non è nemmeno necessario specificare il percorso del certificato radice del server con $ ENV {PERL_LWP_SSL_CA_FILE}.

1

In effetti questo è un po 'disordinato. A seconda della configurazione LWP :: UserAgent può utilizzare uno (almeno) due moduli SSL per gestire la connessione SSL.

  • IO :: Socket :: SSL
  • Net :: SSL

Il primo dovrebbe essere il default per le versioni più recenti di LWP :: UserAgent. È possibile verificare quali di questi sono installati eseguendo il comando standard in un terminale per ogni modulo:

perl -e 'use <module>;' 

IO :: Socket :: SSL richiede la configurazione di SSL con le ssl_opts come nel tuo esempio.

Net: SSL richiede la configurazione SSL nelle variabili di ambiente come nella risposta di goddogsrunnings.

Personalmente cado nella seconda categoria e mi sono ispirato allo Crypt::SSLeay page. In particolare la sezione denominata "SUPPORTO DEL CERTIFICATO DEL CLIENTE".

Problemi correlati