Subject: | feature request: Fallback on Alien::LibreSSL when detection logic fails |
I've been working on my own Alien::LibreSSL and patches to Alien::OpenSSL to see if I could get one or both of them working with Net::SSLeay. The advantages of this can be seen clearly on platforms which do not provide or do not easily provide OpenSSL, such as OS X and Windows. I now have Alien::LibreSSL installing reliably on common cpantester platforms as can be seen here: http://matrix.cpantesters.org/?dist=Alien-LibreSSL+0.02 .
I have also made progress on improving Alien::OpenSSL (seen here https://github.com/plicease/Alien-OpenSSL/commits/alien-build ), but I consider the build process not reliable on important platforms such as Strawberry Perl. I am happy to go into further detail and am open to considering further improvements to Alien::OpenSSL that would address this. I care more that Net::SSLeay is as painless as possible to install than the exact method that is used to reduce said pain.
I am submitting the attached patch which allows Net::SSLeay to fallback on Alien::LibreSSL in the event that it cannot discover the system openssl on its own. It also tests to see if the include path is correct on platforms that have ExtUtils::CBuilder (I believe this is in core Perl 5.10 and better). This is critical because the current detection logic finds the openssl on OS X based on the openssl executable, which does not include out of the box sufficient development files to actually build Net::SSLeay. You will have similar failures on Linux and others if the OpenSSL development package is not installed.
I also found a variable declaration which breaks the compile on older C compilers while testing this with Visual C++ Perl.
Apply this patch shouldn't introduce any new failures, and the fallback would allow Net::SSLeay to install in a number of places where it currently does not. It doesn't add any new dependencies in the case that the system OpenSSL is already installed. I feel that this approach can do the most help with the least amount of harm.
Thank you for your consideration.
Subject: | Net-SSLeay.diff |
diff --git a/SSLeay.xs b/SSLeay.xs
index 67acfe0..10dbb4a 100644
--- a/SSLeay.xs
+++ b/SSLeay.xs
@@ -849,13 +849,15 @@ int ssleay_session_secret_cb_invoke(SSL* s, void* secret, int *secret_len,
res = POPi;
if (res) {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ STRLEN newsecretlen;
+#endif
/* See if there is a preferred cipher selected, if so it is an index into the stack */
if (SvIOK(pref_cipher))
*cipher = sk_SSL_CIPHER_value(peer_ciphers, SvIV(pref_cipher));
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
/* Use any new master secret set by the callback function in secret */
- STRLEN newsecretlen;
char* newsecretdata = SvPV(secretsv, newsecretlen);
memcpy(secret, newsecretdata, newsecretlen);
#endif
diff --git a/inc/Module/Install/PRIVATE/Net/SSLeay.pm b/inc/Module/Install/PRIVATE/Net/SSLeay.pm
index ad0203a..e89637a 100644
--- a/inc/Module/Install/PRIVATE/Net/SSLeay.pm
+++ b/inc/Module/Install/PRIVATE/Net/SSLeay.pm
@@ -26,25 +26,53 @@ sub ssleay {
my $prefix = $self->find_openssl_prefix;
my $exec = $self->find_openssl_exec($prefix);
- unless (-x $exec) {
- print <<EOM;
-*** Could not find OpenSSL
- If it's already installed, please set the OPENSSL_PREFIX environment
- variable accordingly. If it isn't installed yet, get the latest version
- from http://www.openssl.org/.
-EOM
- exit 0; # according http://wiki.cpantesters.org/wiki/CPANAuthorNotes this is best-practice when "missing library"
- }
+ if (-x $exec) {
+ $self->check_openssl_version($prefix, $exec);
+ my $opts = $self->ssleay_get_build_opts($prefix, $exec);
+
+ if (eval { require ExtUtils::CBuilder }) {
+ my $source = 'test.c';
+ open(my $fh, '>', $source);
+ print $fh "#include <openssl/err.h>\n";
+ close $fh;
+ my $b = ExtUtils::CBuilder->new;
+ my $object = eval {
+ $b->compile(
+ source => $source,
+ include_dirs => [$opts->{inc_paths}],
+ );
+ };
+
+ if ($object) {
+ unlink $object;
+ $self->makemaker_args(
+ CCCDLFLAGS => $opts->{cccdlflags},
+ OPTIMIZE => $opts->{optimize},
+ INC => join(' ', map qq{"-I$_"}, @{$opts->{inc_paths}}),
+ LIBS => join(' ', (map qq{"-L$_"}, @{$opts->{lib_paths}}), (map {"-l$_"} @{$opts->{lib_links}})),
+ );
+
+ } else {
+ undef $exec;
- $self->check_openssl_version($prefix, $exec);
- my $opts = $self->ssleay_get_build_opts($prefix, $exec);
+ }
+
+ unlink $source;
+ }
+ }
- $self->makemaker_args(
- CCCDLFLAGS => $opts->{cccdlflags},
- OPTIMIZE => $opts->{optimize},
- INC => join(' ', map qq{"-I$_"}, @{$opts->{inc_paths}}),
- LIBS => join(' ', (map qq{"-L$_"}, @{$opts->{lib_paths}}), (map {"-l$_"} @{$opts->{lib_links}})),
- );
+ if (! -x $exec) {
+
+ $self->makemaker_args(
+ CC => '$(FULLPERL) -MAlien::Base::Wrapper=Alien::LibreSSL -e cc --',
+ LD => '$(FULLPERL) -MAlien::Base::Wrapper=Alien::LibreSSL -e ld --',
+ BUILD_REQUIRES => {
+ 'Alien::LibreSSL' => 0,
+ 'Alien::Base::Wrapper' => 0,
+ },
+ );
+
+ }
if ( $self->prompt(
"Do you want to run external tests?\n".