File Coverage

blib/lib/Crypt/OpenSSL/Guess.pm
Criterion Covered Total %
statement 26 106 24.5
branch 0 58 0.0
condition 0 30 0.0
subroutine 9 17 52.9
pod 5 6 83.3
total 40 217 18.4


line stmt bran cond sub pod time code
1             package Crypt::OpenSSL::Guess;
2 1     1   900 use 5.008001;
  1         3  
3 1     1   7 use strict;
  1         2  
  1         23  
4 1     1   5 use warnings;
  1         2  
  1         47  
5              
6             our $VERSION = "0.13";
7              
8 1     1   6 use Config;
  1         1  
  1         60  
9 1     1   765 use English qw( $OSNAME -no_match_vars );
  1         1983  
  1         7  
10 1     1   225 use File::Spec;
  1         3  
  1         35  
11 1     1   554 use Symbol qw(gensym);
  1         938  
  1         74  
12              
13 1     1   9 use Exporter 'import';
  1         2  
  1         693  
14              
15             our @EXPORT = qw(openssl_inc_paths openssl_lib_paths find_openssl_prefix find_openssl_exec openssl_version);
16              
17             sub openssl_inc_paths {
18 0     0 1   my $prefix = find_openssl_prefix();
19 0           my $exec = find_openssl_exec($prefix);
20              
21 0 0         return '' unless -x $exec;
22              
23 0           my @inc_paths;
24              
25             my @try_includes = (
26 0     0     'include' => sub { 1 },
27 0     0     'inc32' => sub { $OSNAME eq 'MSWin32' },
28 0           );
29              
30 0   0       while (
      0        
31             !@inc_paths
32             && defined( my $dir = shift @try_includes )
33             && defined( my $cond = shift @try_includes )
34             ) {
35 0 0 0       if ( $cond->() && -f "$prefix/$dir/openssl/ssl.h" ) {
36 0           @inc_paths = "$prefix/$dir";
37             }
38             }
39              
40 0           return join ' ', map { "-I$_" } @inc_paths;
  0            
41             }
42              
43             sub openssl_lib_paths {
44 0     0 1   my $prefix = find_openssl_prefix();
45 0           my $exec = find_openssl_exec($prefix);
46              
47 0 0         return '' unless -x $exec;
48              
49 0           my @lib_paths;
50 0           for ($prefix, "$prefix/lib64", "$prefix/lib", "$prefix/out32dll") {
51 0 0         push @lib_paths, $_ if -d $_;
52             }
53              
54 0 0         if ($^O eq 'MSWin32') {
    0          
55 0 0         push @lib_paths, "$prefix/lib/VC" if -d "$prefix/lib/VC";
56              
57 0           my $found = 0;
58 0           my @pairs = ();
59             # Library names depend on the compiler
60 0 0         @pairs = (['eay32','ssl32'],['crypto.dll','ssl.dll'],['crypto','ssl']) if $Config{cc} =~ /gcc/;
61 0 0         @pairs = (['libeay32','ssleay32'],['libeay32MD','ssleay32MD'],['libeay32MT','ssleay32MT'],['libcrypto','libssl'],['crypto','ssl']) if $Config{cc} =~ /cl/;
62 0           for my $dir (@lib_paths) {
63 0           for my $p (@pairs) {
64 0 0 0       $found = 1 if ($Config{cc} =~ /gcc/ && -f "$dir/lib$p->[0].a" && -f "$dir/lib$p->[1].a");
      0        
65 0 0 0       $found = 1 if ($Config{cc} =~ /cl/ && -f "$dir/$p->[0].lib" && -f "$dir/$p->[1].lib");
      0        
66 0 0         if ($found) {
67 0           @lib_paths = ($dir);
68 0           last;
69             }
70             }
71             }
72             }
73             elsif ($^O eq 'VMS') {
74 0 0         if (-r 'sslroot:[000000]openssl.cnf') { # openssl.org source install
    0          
    0          
75 0           @lib_paths = ('SSLLIB');
76             }
77             elsif (-r 'ssl1$root:[000000]openssl.cnf') { # VSI or HPE SSL1 install
78 0           @lib_paths = ('SYS$SHARE');
79             }
80             elsif (-r 'ssl$root:[000000]openssl.cnf') { # HP install
81 0           @lib_paths = ('SYS$SHARE');
82             }
83             }
84              
85 0           return join ' ', map { "-L$_" } @lib_paths;
  0            
86             }
87              
88             my $other_try = 0;
89             my @nopath;
90             sub check_no_path { # On OS/2 it would be typically on default paths
91 0     0 0   my $p;
92 0 0 0       if (not($other_try++) and $] >= 5.008001) {
93 1     1   562 use ExtUtils::MM;
  1         120169  
  1         730  
94 0           my $mm = MM->new();
95 0           my ($list) = $mm->ext("-lssl");
96 0 0         return unless $list =~ /-lssl\b/;
97 0           for $p (split /\Q$Config{path_sep}/, $ENV{PATH}) {
98 0 0         @nopath = ("$p/openssl$Config{_exe}", # exe name
99             '.') # dummy lib path
100             if -x "$p/openssl$Config{_exe}"
101             }
102             }
103 0           @nopath;
104             }
105              
106             sub find_openssl_prefix {
107 0     0 1   my ($dir) = @_;
108              
109 0 0         if (defined $ENV{OPENSSL_PREFIX}) {
110 0           return $ENV{OPENSSL_PREFIX};
111             }
112              
113             # Homebrew (macOS) or LinuxBrew
114 0 0 0       if ($^O ne 'MSWin32' and my $prefix = `brew --prefix --installed openssl 2>@{[File::Spec->devnull]}`) {
115 0           chomp $prefix;
116 0           return $prefix;
117             }
118              
119             my @guesses = (
120             '/home/linuxbrew/.linuxbrew/opt/openssl/bin/openssl' => '/home/linuxbrew/.linuxbrew/opt/openssl', # LinuxBrew openssl
121             '/usr/local/opt/openssl/bin/openssl' => '/usr/local/opt/openssl', # OSX homebrew openssl
122             '/usr/local/bin/openssl' => '/usr/local', # OSX homebrew openssl
123             '/opt/local/bin/openssl' => '/opt/local', # Macports openssl
124             '/usr/bin/openssl' => '/usr',
125             '/usr/sbin/openssl' => '/usr',
126             '/opt/ssl/bin/openssl' => '/opt/ssl',
127             '/opt/ssl/sbin/openssl' => '/opt/ssl',
128             '/usr/local/ssl/bin/openssl' => '/usr/local/ssl',
129             '/usr/local/openssl/bin/openssl' => '/usr/local/openssl',
130             '/apps/openssl/std/bin/openssl' => '/apps/openssl/std',
131             '/usr/sfw/bin/openssl' => '/usr/sfw', # Open Solaris
132             'C:\OpenSSL\bin\openssl.exe' => 'C:\OpenSSL',
133             'C:\OpenSSL-Win32\bin\openssl.exe' => 'C:\OpenSSL-Win32',
134             $Config{prefix} . '\bin\openssl.exe' => $Config{prefix}, # strawberry perl
135 0           $Config{prefix} . '\..\c\bin\openssl.exe' => $Config{prefix} . '\..\c', # strawberry perl
136             '/sslexe/openssl.exe' => '/sslroot', # VMS, openssl.org
137             '/ssl1$exe/openssl.exe' => '/ssl1$root',# VMS, VSI or HPE install
138             '/ssl$exe/openssl.exe' => '/ssl$root', # VMS, HP install
139             );
140              
141 0   0       while (my $k = shift @guesses
142             and my $v = shift @guesses) {
143 0 0         if ( -x $k ) {
144 0           return $v;
145             }
146             }
147 0 0         (undef, $dir) = check_no_path()
148             and return $dir;
149              
150 0           return;
151             }
152              
153             sub find_openssl_exec {
154 0     0 1   my ($prefix) = @_;
155              
156 0           my $exe_path;
157 0           for my $subdir (qw( bin sbin out32dll ia64_exe alpha_exe )) {
158 0           my $path = File::Spec->catfile($prefix, $subdir, "openssl$Config{_exe}");
159 0 0         if ( -x $path ) {
160 0           return $path;
161             }
162             }
163 0 0         ($prefix) = check_no_path()
164             and return $prefix;
165 0           return;
166             }
167              
168             sub openssl_version {
169 0     0 1   my ($major, $minor, $letter);
170              
171 0           my $prefix = find_openssl_prefix();
172 0           my $exec = find_openssl_exec($prefix);
173              
174 0 0         return unless -x $exec;
175              
176             {
177 0           my $pipe = gensym();
  0            
178 0 0         open($pipe, qq{"$exec" version |})
179             or die "Could not execute $exec";
180 0           my $output = <$pipe>;
181 0           chomp $output;
182 0           close $pipe;
183              
184 0 0         if ( ($major, $minor, $letter) = $output =~ /^OpenSSL\s+(\d+\.\d+)\.(\d+)([a-z]?)/ ) {
    0          
185             } elsif ( ($major, $minor) = $output =~ /^LibreSSL\s+(\d+\.\d+)(?:\.(\d+))?/ ) {
186             # LibreSSL 2.0.x releases only identify themselves as "LibreSSL 2.0",
187             # with no patch release number
188 0 0         if ( !defined $minor ) {
189 0           $minor = "x";
190             }
191             } else {
192 0           die <
193             *** OpenSSL version test failed
194             (`$output' has been returned)
195             Either you have bogus OpenSSL or a new version has changed the version
196             number format. Please inform the authors!
197             EOM
198             }
199             }
200              
201 0           return ($major, $minor, $letter);
202             }
203              
204             1;
205             __END__