1*4724848cSchristos# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. 2*4724848cSchristos# 3*4724848cSchristos# Licensed under the OpenSSL license (the "License"). You may not use 4*4724848cSchristos# this file except in compliance with the License. You can obtain a copy 5*4724848cSchristos# in the file LICENSE in the source distribution or at 6*4724848cSchristos# https://www.openssl.org/source/license.html 7*4724848cSchristos 8*4724848cSchristospackage OpenSSL::Test::Utils; 9*4724848cSchristos 10*4724848cSchristosuse strict; 11*4724848cSchristosuse warnings; 12*4724848cSchristos 13*4724848cSchristosuse Exporter; 14*4724848cSchristosuse vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); 15*4724848cSchristos$VERSION = "0.1"; 16*4724848cSchristos@ISA = qw(Exporter); 17*4724848cSchristos@EXPORT = qw(alldisabled anydisabled disabled config available_protocols 18*4724848cSchristos have_IPv4 have_IPv6); 19*4724848cSchristos 20*4724848cSchristos=head1 NAME 21*4724848cSchristos 22*4724848cSchristosOpenSSL::Test::Utils - test utility functions 23*4724848cSchristos 24*4724848cSchristos=head1 SYNOPSIS 25*4724848cSchristos 26*4724848cSchristos use OpenSSL::Test::Utils; 27*4724848cSchristos 28*4724848cSchristos my @tls = available_protocols("tls"); 29*4724848cSchristos my @dtls = available_protocols("dtls"); 30*4724848cSchristos alldisabled("dh", "dsa"); 31*4724848cSchristos anydisabled("dh", "dsa"); 32*4724848cSchristos 33*4724848cSchristos config("fips"); 34*4724848cSchristos 35*4724848cSchristos have_IPv4(); 36*4724848cSchristos have_IPv6(); 37*4724848cSchristos 38*4724848cSchristos=head1 DESCRIPTION 39*4724848cSchristos 40*4724848cSchristosThis module provides utility functions for the testing framework. 41*4724848cSchristos 42*4724848cSchristos=cut 43*4724848cSchristos 44*4724848cSchristosuse OpenSSL::Test qw/:DEFAULT bldtop_file/; 45*4724848cSchristos 46*4724848cSchristos=over 4 47*4724848cSchristos 48*4724848cSchristos=item B<available_protocols STRING> 49*4724848cSchristos 50*4724848cSchristosReturns a list of strings for all the available SSL/TLS versions if 51*4724848cSchristosSTRING is "tls", or for all the available DTLS versions if STRING is 52*4724848cSchristos"dtls". Otherwise, it returns the empty list. The strings in the 53*4724848cSchristosreturned list can be used with B<alldisabled> and B<anydisabled>. 54*4724848cSchristos 55*4724848cSchristos=item B<alldisabled ARRAY> 56*4724848cSchristos=item B<anydisabled ARRAY> 57*4724848cSchristos 58*4724848cSchristosIn an array context returns an array with each element set to 1 if the 59*4724848cSchristoscorresponding feature is disabled and 0 otherwise. 60*4724848cSchristos 61*4724848cSchristosIn a scalar context, alldisabled returns 1 if all of the features in 62*4724848cSchristosARRAY are disabled, while anydisabled returns 1 if any of them are 63*4724848cSchristosdisabled. 64*4724848cSchristos 65*4724848cSchristos=item B<config STRING> 66*4724848cSchristos 67*4724848cSchristosReturns an item from the %config hash in \$TOP/configdata.pm. 68*4724848cSchristos 69*4724848cSchristos=item B<have_IPv4> 70*4724848cSchristos=item B<have_IPv6> 71*4724848cSchristos 72*4724848cSchristosReturn true if IPv4 / IPv6 is possible to use on the current system. 73*4724848cSchristos 74*4724848cSchristos=back 75*4724848cSchristos 76*4724848cSchristos=cut 77*4724848cSchristos 78*4724848cSchristosour %available_protocols; 79*4724848cSchristosour %disabled; 80*4724848cSchristosour %config; 81*4724848cSchristosmy $configdata_loaded = 0; 82*4724848cSchristos 83*4724848cSchristossub load_configdata { 84*4724848cSchristos # We eval it so it doesn't run at compile time of this file. 85*4724848cSchristos # The latter would have bldtop_file() complain that setup() hasn't 86*4724848cSchristos # been run yet. 87*4724848cSchristos my $configdata = bldtop_file("configdata.pm"); 88*4724848cSchristos eval { require $configdata; 89*4724848cSchristos %available_protocols = %configdata::available_protocols; 90*4724848cSchristos %disabled = %configdata::disabled; 91*4724848cSchristos %config = %configdata::config; 92*4724848cSchristos }; 93*4724848cSchristos $configdata_loaded = 1; 94*4724848cSchristos} 95*4724848cSchristos 96*4724848cSchristos# args 97*4724848cSchristos# list of 1s and 0s, coming from check_disabled() 98*4724848cSchristossub anyof { 99*4724848cSchristos my $x = 0; 100*4724848cSchristos foreach (@_) { $x += $_ } 101*4724848cSchristos return $x > 0; 102*4724848cSchristos} 103*4724848cSchristos 104*4724848cSchristos# args 105*4724848cSchristos# list of 1s and 0s, coming from check_disabled() 106*4724848cSchristossub allof { 107*4724848cSchristos my $x = 1; 108*4724848cSchristos foreach (@_) { $x *= $_ } 109*4724848cSchristos return $x > 0; 110*4724848cSchristos} 111*4724848cSchristos 112*4724848cSchristos# args 113*4724848cSchristos# list of strings, all of them should be names of features 114*4724848cSchristos# that can be disabled. 115*4724848cSchristos# returns a list of 1s (if the corresponding feature is disabled) 116*4724848cSchristos# and 0s (if it isn't) 117*4724848cSchristossub check_disabled { 118*4724848cSchristos return map { exists $disabled{lc $_} ? 1 : 0 } @_; 119*4724848cSchristos} 120*4724848cSchristos 121*4724848cSchristos# Exported functions ################################################# 122*4724848cSchristos 123*4724848cSchristos# args: 124*4724848cSchristos# list of features to check 125*4724848cSchristossub anydisabled { 126*4724848cSchristos load_configdata() unless $configdata_loaded; 127*4724848cSchristos my @ret = check_disabled(@_); 128*4724848cSchristos return @ret if wantarray; 129*4724848cSchristos return anyof(@ret); 130*4724848cSchristos} 131*4724848cSchristos 132*4724848cSchristos# args: 133*4724848cSchristos# list of features to check 134*4724848cSchristossub alldisabled { 135*4724848cSchristos load_configdata() unless $configdata_loaded; 136*4724848cSchristos my @ret = check_disabled(@_); 137*4724848cSchristos return @ret if wantarray; 138*4724848cSchristos return allof(@ret); 139*4724848cSchristos} 140*4724848cSchristos 141*4724848cSchristos# !!! Kept for backward compatibility 142*4724848cSchristos# args: 143*4724848cSchristos# single string 144*4724848cSchristossub disabled { 145*4724848cSchristos anydisabled(@_); 146*4724848cSchristos} 147*4724848cSchristos 148*4724848cSchristossub available_protocols { 149*4724848cSchristos load_configdata() unless $configdata_loaded; 150*4724848cSchristos my $protocol_class = shift; 151*4724848cSchristos if (exists $available_protocols{lc $protocol_class}) { 152*4724848cSchristos return @{$available_protocols{lc $protocol_class}} 153*4724848cSchristos } 154*4724848cSchristos return (); 155*4724848cSchristos} 156*4724848cSchristos 157*4724848cSchristossub config { 158*4724848cSchristos load_configdata() unless $configdata_loaded; 159*4724848cSchristos return $config{$_[0]}; 160*4724848cSchristos} 161*4724848cSchristos 162*4724848cSchristos# IPv4 / IPv6 checker 163*4724848cSchristosmy $have_IPv4 = -1; 164*4724848cSchristosmy $have_IPv6 = -1; 165*4724848cSchristosmy $IP_factory; 166*4724848cSchristossub check_IP { 167*4724848cSchristos my $listenaddress = shift; 168*4724848cSchristos 169*4724848cSchristos eval { 170*4724848cSchristos require IO::Socket::IP; 171*4724848cSchristos my $s = IO::Socket::IP->new( 172*4724848cSchristos LocalAddr => $listenaddress, 173*4724848cSchristos LocalPort => 0, 174*4724848cSchristos Listen=>1, 175*4724848cSchristos ); 176*4724848cSchristos $s or die "\n"; 177*4724848cSchristos $s->close(); 178*4724848cSchristos }; 179*4724848cSchristos if ($@ eq "") { 180*4724848cSchristos return 1; 181*4724848cSchristos } 182*4724848cSchristos 183*4724848cSchristos eval { 184*4724848cSchristos require IO::Socket::INET6; 185*4724848cSchristos my $s = IO::Socket::INET6->new( 186*4724848cSchristos LocalAddr => $listenaddress, 187*4724848cSchristos LocalPort => 0, 188*4724848cSchristos Listen=>1, 189*4724848cSchristos ); 190*4724848cSchristos $s or die "\n"; 191*4724848cSchristos $s->close(); 192*4724848cSchristos }; 193*4724848cSchristos if ($@ eq "") { 194*4724848cSchristos return 1; 195*4724848cSchristos } 196*4724848cSchristos 197*4724848cSchristos eval { 198*4724848cSchristos require IO::Socket::INET; 199*4724848cSchristos my $s = IO::Socket::INET->new( 200*4724848cSchristos LocalAddr => $listenaddress, 201*4724848cSchristos LocalPort => 0, 202*4724848cSchristos Listen=>1, 203*4724848cSchristos ); 204*4724848cSchristos $s or die "\n"; 205*4724848cSchristos $s->close(); 206*4724848cSchristos }; 207*4724848cSchristos if ($@ eq "") { 208*4724848cSchristos return 1; 209*4724848cSchristos } 210*4724848cSchristos 211*4724848cSchristos return 0; 212*4724848cSchristos} 213*4724848cSchristos 214*4724848cSchristossub have_IPv4 { 215*4724848cSchristos if ($have_IPv4 < 0) { 216*4724848cSchristos $have_IPv4 = check_IP("127.0.0.1"); 217*4724848cSchristos } 218*4724848cSchristos return $have_IPv4; 219*4724848cSchristos} 220*4724848cSchristos 221*4724848cSchristossub have_IPv6 { 222*4724848cSchristos if ($have_IPv6 < 0) { 223*4724848cSchristos $have_IPv6 = check_IP("::1"); 224*4724848cSchristos } 225*4724848cSchristos return $have_IPv6; 226*4724848cSchristos} 227*4724848cSchristos 228*4724848cSchristos 229*4724848cSchristos=head1 SEE ALSO 230*4724848cSchristos 231*4724848cSchristosL<OpenSSL::Test> 232*4724848cSchristos 233*4724848cSchristos=head1 AUTHORS 234*4724848cSchristos 235*4724848cSchristosStephen Henson E<lt>steve@openssl.orgE<gt> and 236*4724848cSchristosRichard Levitte E<lt>levitte@openssl.orgE<gt> 237*4724848cSchristos 238*4724848cSchristos=cut 239*4724848cSchristos 240*4724848cSchristos1; 241