Hello monks!

I had to add a filter to an old program that uses WWW::Salesforce::Simple and was packaged in an EXE (for Windows) using pp, but after the change in a up-to-date Activeperl distribution, I got:

500 Can't connect to www.salesforce.com:443 at WWW/Salesforce.pm line 497.

As the perl script runs OK when invoqued from the command line, but fails in the EXE, I tried to find the problem tracing the files manually (with a text editor).

I've spend many days tracking this issue reading docs, RT bug reports, and posts in many forums, but always far away the real root of the problem.

I started by searching which script in perl library generates that error message. As I found some, I tried to discard the ones that were not packaged in the EXE by looking the dependencies. First, I tried some tracing tools like Devel::Trace, but it doesn't work in EXE as I couldn't figure out how to pass -d:Trace argument to it (I even tried placing it in the first line of my script). Then I found that @INC has the info I wanted. Later, I learned that renaming the EXE file as ZIP, I could browse it contents.

I did a directory compare from the extracted files from the old and new EXE, and identified which modules have changed lately, specially those that are dependencies of WWW::Salesforce module. The most relevant ones where related to HTTPS and SSL.

I found a hint somewhere in this site about including the following in my script to enable a trace in that module:

use IO::Socket::SSL qw(debug99);

Gotcha! It is not being able to load the SSL CA certificates, which is mandatory (and the default) to verify host names for HTTPS connections from some time ago. A quick review to the contents of the ZIP archive (renamed EXE file), I could confirm that cacert.pem file was not included with the Mozilla::CA module. The workaround was to compile with the following option in pp:

-a "C:\Perl\lib\Mozilla\CA\cacert.pem;lib/Mozilla/CA/cacert.pem"

Actually, I tried many forms of that argument until it was stored in the proper directory inside the package (EXE file). But it didn't work!!! The file remained unable to be loaded by Net::SSLeay module.

Some debug instructions introduced in IO::Socket::SSL pointed to LWP::Protocol::https, which in turn pointed again to Mozilla::CA.

Debugging CA.pm file from Mozilla::CA, I found the following line:

my $file = File::Spec->catfile(dirname(__FILE__), "CA", "cacert.pe +m");

The problem was the __FILE__ token, which returns an absolute path when running perl in command line, but a relative path if run when packed with PAR::Packer into the EXE file. There is a RT report about this in another context, where a workaround was done.

CA.pm tried to transform a relative path into an absolute one unsuccessfully using Cwd, which appended the location of the EXE file to the path instead the real cache area location that PAR uses in runtime.

My workaround for this case required to find how to get the current temp dir for the cache, and I found it inside @INC, so I changed the previous line into this one:

my $file = File::Spec->catfile(dirname($INC{'Mozilla/CA.pm'}), "CA +", "cacert.pem");

This way, the Mozilla::CA module works fine both in command line and inside an EXE file.

Happy end? No... I need some help in the following:

  1. I also found that some of the paths inside the @INC do not have an absolute path to real disk but something in the form of /loader/HASH(0x1342b2c)/Cwd.pm. If sometime in the future the absolute path for Mozilla/CA.pm changes to a hash like that, this workaround will fail. Do someone have a better solution to get the real temporary cache location?
  2. I had to add the cacert.pem file manually with -a option for pp, because Module::ScanDeps didn't include this in the list. Is there a way to force the addition of it directly modifying the Mozilla::CA module?
  3. I guess that the keys included in cacert.pem file will expire sometime. Does this mean that I'd have to "recompile" all my programs that use SSL after every update of the Mozilla::CA module?

Thanks in advance!


In reply to __FILE__, pp (PAR::Packer) and extra files by vitoco

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.