Jacinta Alice Richardson wrote:
> Dear Gisle Aas     author of libwww-perl
>      Joshua Chamas author of Crypt::SSLeay 
>      Graham Barr   author of perl-ldap  and
>      Marko Asplund author of IO::Socket::SSL
> 
> First of all, I'd like to say thanks for writing a great set of packages
> and releasing them to CPAN for the good of all.
> 
> I'm writing to you today due to a problem I have had when trying to use
> these packages in combination, specificially I was trying to use
> LWP::UserAgent for HTTP SSL connections as well as Net::LDAPS for LDAP SSL
> connections in the same application.  To the best of my knowledge these
> both rely on IO::Socket::SSL.
> 

Please post messages such as this in the future to [EMAIL PROTECTED]
which is the LWP support mailing list.  Posting such questions
directly to authors is less good for all of us usually.  You just
happened to catch me at a good time, but this is not normally
the case! :)

The problem here I believe is IO::Socket::SSL not working with
LWP to connect to your web site, where Crypt::SSLeay does.
With perl 5.8, & recent IO::Socket::SSL & LWP, openssl 0.9.6d,
I was not able to connect to https://www.nodeworks.com, but when
using Crypt::SSLeay instead of IO::Socket::SSL, I was.

Net::LDAPS loads IO::Socket::SSL on the back end it seems,
so if you use the former, LWP will try to use IO::Socket::SSL
for its https connections.

To work around this problem for the moment, you might
undef $IO::Socket::SSL::VERSION

   $IO::Socket::SSL::VERSION = undef;

AFTER you load Net::LDAPS or IO::Socket::SSL ( might as well
"use IO::Socket::SSL" explicity ).  This work around however would
break as soon as LWP detects IO::Socket::SSL a different way.

A better long term fix is for LWP & IO::Socket::SSL to work
on your platform.  It did not on mine.  Getting IO::Socket::SSL
to work is not something I will try, but you are more than
welcome to dive into the code & send a patch to the author
if you find the problem.

Regards,

Josh
________________________________________________________________
Josh Chamas, Founder                   phone:714-625-4051
Chamas Enterprises Inc.                http://www.chamas.com
NodeWorks Link Checking                http://www.nodeworks.com


> My problem was the following:
> 
> My current job at work is to alter a very successful student service site
> to play nicely with a portal we've just bought.
> 
> Currently we require the students to submit their PIN with every change to
> their details and hope that that can be avoided with the portal. The first
> time that the student comes in from the portal they'll hit a basic auth
> page and submit their username and password. From then on the portal will
> submit their details to my site and no further PIN or password will be
> needed.
> 
> Unfortunately their username will not be their student number, so I need
> to make an LDAP query to our LDAP server to get their student number based
> on their username. This is easy, I'm using perl-ldap version 0.26. (I did
> try perldap but had too much trouble getting it to install on our alpha
> machine).
> 
> The machine that our (Forte) database (with all the student's course
> details etc) is on is different from where we host the student service.
> Access for information and updates for changes are made by web requests
> over SSL. This is easy, I'm using the libwww-perl libraries version 5.65.
> 
> My problem is that I can very easily get the student's student number from
> LDAP or I can very easily access Forte, but for some reason I can't do
> both.
> 
> Originally my code looked like this (heavily simplified):
> 
>         ### Forte.pm
> package Forte;
> use LWP::UserAgent;
> 
> $ENV{HTTPS_VERSION} = '3';
> $ENV{HTTPS_CERT_FILE} = "some.crt";
> $ENV{HTTPS_KEY_FILE} = "some.key";
> 
> sub callforte
> {
>         ...
>         my $ua = new LWP::UserAgent;
>         my $req = new HTTP::Request("POST", "$url");
>         ...
>         my $res = $ua->request($req);
>         ...
> }
> 
> #------------------------------------------
>         ### LDAP.pm
> package LDAP;
> use Net::LDAPS;
> 
> sub LDAP_connect
> {
>         ....
>         my $conn = new Net::LDAPS($LDAPhost,
>                                   port=>$LDAPport,
>                                   clientcert=>$cert,
>                                   clientkey=>$key);
>         ....
> }
> 
> sub get_student_number
> {
>         LDAP_connect();
>         ...
>         my $entry = $conn->search(filter=>"(uid=$username)",
>                                  base=>$base,
>                                  attrs=>[qw/studentnumber/]);
>         if($entry->code())
>         {
>                 html_error("Search for student ID for [$username] " .
>                            "failed:". $entry->code() . "\n");
>                 return 0;
>         }
> 
>         ...
>         return $entry->{attrs}{studentnumber}[0];
> }
> 
> #------------------------------------------
>         #### application
> use Forte;
> use LDAP;
> 
>         # test for connection to db:
> $return = Forte::callforte($url, $input);
> 
> ...
> 
> if($using_portal)
> {
>         # get student number
>         $student_number = LDAP::get_student_number($username);
> }
> 
> 
> I found that if I commented out "use LDAP;" and set "$using_portal" to
> false, everything worked as it should, the "$ua->request($req);" takes
> some time and returns with code 200 (and any data I want). If I leave
> "$using_portal" false, but uncomment "use LDAP;" then when I attempt to
> connect to the Forte database the "$ua->request($req);" line returns
> immediately with error code 500.  The same happened just with commenting
> out "use Net::LDAPS;"
> 
> The dependencies (that I know about) and the versions I have installed are
> as follows:
> 
>     * libwww-perl
>           o Crypt::SSLeay (version 0.41)
>           o IO::Socket::SSL (version 0.81)
>     * perl-ldap
>           o Convert::ASN1 (version 0.15)
>           o IO::Socket::SSL (version 0.81)
>           o Ne::SSLeay (version 1.18)
>           o URI (version 1.19)
>           o URI::ldap
>           o Digest::MD5 (version 2.20)
>           o XML::Parser (version 2.31)
>           o MIME::Base64 (version 2.12)
>           o Authen::SASL (version 2.02)
> 
> "perl -v" yields: This is perl, v5.6.1 built for alpha-dec_osf
> 
> Using "Net::LDAP" and TLS would be a great idea, but TLS isn't supported
> in our current LDAP server (iplanet 4.1 I believe).  It is supported in
> 5.1 but the migration of our data is not trivial.
> 
> I later simplified the code to:
> 
> 
> #!/servers/web/bin/perl -w
> use strict;
> 
> use IO::Socket::SSL;
> use LWP::UserAgent;
> use Data::Dumper;
> 
>         ### LWP Stuff
> $ENV{HTTPS_VERSION} = '3';
> # CLIENT CERT SUPPORT
> 
>        ### These ENV variables are required by LWP, there
>        ### exists no other method of telling LWP which
>        ### certificates should be used.
> my $certdbpath = "/some/cert/path/conf/";
> $ENV{HTTPS_CERT_FILE} = "$certdbpath/client.crt";
> $ENV{HTTPS_KEY_FILE}  = "$certdbpath/client.key";
> 
> callforte();
> 
> exit;
> 
> ##############################################
> 
> sub callforte
> {
>         print "This is libwww-perl-$LWP::VERSION\n";
>         print STDERR "This is libwww-perl-$LWP::VERSION\n";
> 
>                 # Check we have permission to read the certificates.
>         open CERT, $ENV{HTTPS_CERT_FILE} or die "not cert :(";
>         open KEY, $ENV{HTTPS_KEY_FILE} or die "not key :(";
> 
>         my $ua = new LWP::UserAgent;
>         my $req = new HTTP::Request('POST',
>                    'https://machine.edu.au:123443/cgi-bin/fortecgi?'.
>                   'pagename=CheckForte');
> 
>                 # This is an HTML form
>         $req->content_type('application/x-www-form-urlencoded');
> 
>         $req->content("dummy_input=1");
> 
>         my $res = $ua->request($req);
> 
>         print STDERR $res->code."\n";
>         print STDERR $res->content(), "\n";
>         print Dumper($res);
>         return "";
> }
> 
> with the same problem.
> 
> When I attempt my LWP connection, the HTTP::Response _msg is "Can't
> connect to machine.edu.au:123443 ()". However no message is recorded in
> the server error logs and no access attempt is recorded in the server
> access logs.
> 
> Doing a watch of netstat -tn on the forte machine records tcp connections
> when the script is run without IO::Socket::SSL but none when that code is
> included. Since these connections stick around for a few minutes I suspect
> that it isn't just because the script connects and then disconnects super
> fast.
> 
> A separate test, changing the host I'm trying to connect to, yeilds
> similar results. Attempting to connect to https://www.unimelb.edu.au fails
> in exactly the same manner, but connecting to http://www.unimelb.edu.au
> responds with a "405: Method Not Allowed" which is good, because the page
> doesn't accept POSTs. 
> 
> I think the ultimate problem is summed up in these two lines of the
> IO::Socket::SSL documentation:
> 
>       Currently, the IO::Socket::INET interface as 
>       implemented by this package is not quite complete. 
>       There can be only one SSL context at a given time.
> 
> And this piece of code:
> 
> #
> # $Id: https10.pm,v 1.1 2001/10/26 17:27:19 gisle Exp $
> 
> use strict;
> 
> package LWP::Protocol::https10;
> 
> # Figure out which SSL implementation to use
> use vars qw($SSL_CLASS);
> if ($IO::Socket::SSL::VERSION) {
>     $SSL_CLASS = "IO::Socket::SSL"; # it was already loaded
> } else {
>     eval { require Net::SSL; };     # from Crypt-SSLeay
>     if ($@) {
>       require IO::Socket::SSL;
>       $SSL_CLASS = "IO::Socket::SSL";
>     } else {
>       $SSL_CLASS = "Net::SSL";
>     }
> }
> 
> 
> However a bigger problem is that this failure is completely silent.  One
> single use statement in my code makes my previously working LWP requests
> silently fail, even when I don't do anything with the module I've loaded!
> 
> I've written this to all of you because I hope this way a solution might
> be found that allows all of these modules to work together in harmony.
> 
> Thanks.
>       Jacinta
> 
> 
> 
> 

Reply via email to