File Coverage

blib/lib/Crypt/OpenSSL/Guess.pm
Criterion Covered Total %
statement 26 110 23.6
branch 0 62 0.0
condition 0 33 0.0
subroutine 9 17 52.9
pod 5 6 83.3
total 40 228 17.5


line stmt bran cond sub pod time code
1             package Crypt::OpenSSL::Guess;
2 1     1   550 use 5.008001;
  1         2  
3 1     1   3 use strict;
  1         1  
  1         15  
4 1     1   3 use warnings;
  1         1  
  1         26  
5              
6             our $VERSION = "0.15";
7              
8 1     1   5 use Config;
  1         1  
  1         47  
9 1     1   1305 use English qw( $OSNAME -no_match_vars );
  1         1874  
  1         3  
10 1     1   125 use File::Spec;
  1         1  
  1         20  
11 1     1   365 use Symbol qw(gensym);
  1         557  
  1         43  
12              
13 1     1   5 use Exporter 'import';
  1         2  
  1         515  
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          
    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 'darwin') {
74 0           for my $dir (@lib_paths) {
75 0 0 0       if (-f "$dir/libcrypto.dylib" && -f "$dir/libssl.dylib") {
76 0           @lib_paths = ($dir);
77 0           last;
78             }
79             }
80             }
81             elsif ($^O eq 'VMS') {
82 0 0         if (-r 'sslroot:[000000]openssl.cnf') { # openssl.org source install
    0          
    0          
83 0           @lib_paths = ('SSLLIB');
84             }
85             elsif (-r 'ssl1$root:[000000]openssl.cnf') { # VSI or HPE SSL1 install
86 0           @lib_paths = ('SYS$SHARE');
87             }
88             elsif (-r 'ssl$root:[000000]openssl.cnf') { # HP install
89 0           @lib_paths = ('SYS$SHARE');
90             }
91             }
92              
93 0           return join ' ', map { "-L$_" } @lib_paths;
  0            
94             }
95              
96             my $other_try = 0;
97             my @nopath;
98             sub check_no_path { # On OS/2 it would be typically on default paths
99 0     0 0   my $p;
100 0 0 0       if (not($other_try++) and $] >= 5.008001) {
101 1     1   338 use ExtUtils::MM;
  1         76987  
  1         456  
102 0           my $mm = MM->new();
103 0           my ($list) = $mm->ext("-lssl");
104 0 0         return unless $list =~ /-lssl\b/;
105 0           for $p (split /\Q$Config{path_sep}/, $ENV{PATH}) {
106 0 0         @nopath = ("$p/openssl$Config{_exe}", # exe name
107             '.') # dummy lib path
108             if -x "$p/openssl$Config{_exe}"
109             }
110             }
111 0           @nopath;
112             }
113              
114             sub find_openssl_prefix {
115 0     0 1   my ($dir) = @_;
116              
117 0 0         if (defined $ENV{OPENSSL_PREFIX}) {
118 0           return $ENV{OPENSSL_PREFIX};
119             }
120              
121             # Homebrew (macOS) or LinuxBrew
122 0 0 0       if ($^O ne 'MSWin32' and my $prefix = `brew --prefix --installed openssl 2>@{[File::Spec->devnull]}`) {
123 0           chomp $prefix;
124 0           return $prefix;
125             }
126              
127             my @guesses = (
128             '/home/linuxbrew/.linuxbrew/opt/openssl/bin/openssl' => '/home/linuxbrew/.linuxbrew/opt/openssl', # LinuxBrew openssl
129             '/opt/homebrew/opt/openssl/bin/openssl' => '/opt/homebrew/opt/openssl', # macOS ARM homebrew
130             '/usr/local/opt/openssl/bin/openssl' => '/usr/local/opt/openssl', # OSX homebrew openssl
131             '/usr/local/bin/openssl' => '/usr/local', # OSX homebrew openssl
132             '/opt/local/bin/openssl' => '/opt/local', # Macports openssl
133             '/usr/bin/openssl' => '/usr',
134             '/usr/sbin/openssl' => '/usr',
135             '/opt/ssl/bin/openssl' => '/opt/ssl',
136             '/opt/ssl/sbin/openssl' => '/opt/ssl',
137             '/usr/local/ssl/bin/openssl' => '/usr/local/ssl',
138             '/usr/local/openssl/bin/openssl' => '/usr/local/openssl',
139             '/apps/openssl/std/bin/openssl' => '/apps/openssl/std',
140             '/usr/sfw/bin/openssl' => '/usr/sfw', # Open Solaris
141             'C:\OpenSSL\bin\openssl.exe' => 'C:\OpenSSL',
142             'C:\OpenSSL-Win32\bin\openssl.exe' => 'C:\OpenSSL-Win32',
143             $Config{prefix} . '\bin\openssl.exe' => $Config{prefix}, # strawberry perl
144 0           $Config{prefix} . '\..\c\bin\openssl.exe' => $Config{prefix} . '\..\c', # strawberry perl
145             '/sslexe/openssl.exe' => '/sslroot', # VMS, openssl.org
146             '/ssl1$exe/openssl.exe' => '/ssl1$root',# VMS, VSI or HPE install
147             '/ssl$exe/openssl.exe' => '/ssl$root', # VMS, HP install
148             );
149              
150 0   0       while (my $k = shift @guesses
151             and my $v = shift @guesses) {
152 0 0         if ( -x $k ) {
153 0           return $v;
154             }
155             }
156 0 0         (undef, $dir) = check_no_path()
157             and return $dir;
158              
159 0           return;
160             }
161              
162             sub find_openssl_exec {
163 0     0 1   my ($prefix) = @_;
164              
165 0           my $exe_path;
166 0           for my $subdir (qw( bin sbin out32dll ia64_exe alpha_exe )) {
167 0           my $path = File::Spec->catfile($prefix, $subdir, "openssl$Config{_exe}");
168 0 0         if ( -x $path ) {
169 0           return $path;
170             }
171             }
172 0 0         ($prefix) = check_no_path()
173             and return $prefix;
174 0           return;
175             }
176              
177             sub openssl_version {
178 0     0 1   my ($major, $minor, $letter);
179              
180 0           my $prefix = find_openssl_prefix();
181 0           my $exec = find_openssl_exec($prefix);
182              
183 0 0         return unless -x $exec;
184              
185             {
186 0           my $pipe = gensym();
  0            
187 0 0         open($pipe, qq{"$exec" version |})
188             or die "Could not execute $exec";
189 0           my $output = <$pipe>;
190 0           chomp $output;
191 0           close $pipe;
192              
193 0 0         if ( ($major, $minor, $letter) = $output =~ /^OpenSSL\s+(\d+\.\d+)\.(\d+)([a-z]?)/ ) {
    0          
194             } elsif ( ($major, $minor) = $output =~ /^LibreSSL\s+(\d+\.\d+)(?:\.(\d+))?/ ) {
195             # LibreSSL 2.0.x releases only identify themselves as "LibreSSL 2.0",
196             # with no patch release number
197 0 0         if ( !defined $minor ) {
198 0           $minor = "x";
199             }
200             } else {
201 0           die <
202             *** OpenSSL version test failed
203             (`$output' has been returned)
204             Either you have bogus OpenSSL or a new version has changed the version
205             number format. Please inform the authors!
206             EOM
207             }
208             }
209              
210 0           return ($major, $minor, $letter);
211             }
212              
213             1;
214             __END__