| # Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. | |
| # | |
| # Licensed under the OpenSSL license (the "License"). You may not use | |
| # this file except in compliance with the License. You can obtain a copy | |
| # in the file LICENSE in the source distribution or at | |
| # https://www.openssl.org/source/license.html | |
| package OpenSSL::Test::Utils; | |
| use strict; | |
| use warnings; | |
| use Exporter; | |
| use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); | |
| $VERSION = "0.1"; | |
| @ISA = qw(Exporter); | |
| @EXPORT = qw(alldisabled anydisabled disabled config available_protocols | |
| have_IPv4 have_IPv6); | |
| =head1 NAME | |
| OpenSSL::Test::Utils - test utility functions | |
| =head1 SYNOPSIS | |
| use OpenSSL::Test::Utils; | |
| my @tls = available_protocols("tls"); | |
| my @dtls = available_protocols("dtls"); | |
| alldisabled("dh", "dsa"); | |
| anydisabled("dh", "dsa"); | |
| config("fips"); | |
| have_IPv4(); | |
| have_IPv6(); | |
| =head1 DESCRIPTION | |
| This module provides utility functions for the testing framework. | |
| =cut | |
| use OpenSSL::Test qw/:DEFAULT bldtop_file/; | |
| =over 4 | |
| =item B<available_protocols STRING> | |
| Returns a list of strings for all the available SSL/TLS versions if | |
| STRING is "tls", or for all the available DTLS versions if STRING is | |
| "dtls". Otherwise, it returns the empty list. The strings in the | |
| returned list can be used with B<alldisabled> and B<anydisabled>. | |
| =item B<alldisabled ARRAY> | |
| =item B<anydisabled ARRAY> | |
| In an array context returns an array with each element set to 1 if the | |
| corresponding feature is disabled and 0 otherwise. | |
| In a scalar context, alldisabled returns 1 if all of the features in | |
| ARRAY are disabled, while anydisabled returns 1 if any of them are | |
| disabled. | |
| =item B<config STRING> | |
| Returns an item from the %config hash in \$TOP/configdata.pm. | |
| =item B<have_IPv4> | |
| =item B<have_IPv6> | |
| Return true if IPv4 / IPv6 is possible to use on the current system. | |
| =back | |
| =cut | |
| our %available_protocols; | |
| our %disabled; | |
| our %config; | |
| my $configdata_loaded = 0; | |
| sub load_configdata { | |
| # We eval it so it doesn't run at compile time of this file. | |
| # The latter would have bldtop_file() complain that setup() hasn't | |
| # been run yet. | |
| my $configdata = bldtop_file("configdata.pm"); | |
| eval { require $configdata; | |
| %available_protocols = %configdata::available_protocols; | |
| %disabled = %configdata::disabled; | |
| %config = %configdata::config; | |
| }; | |
| $configdata_loaded = 1; | |
| } | |
| # args | |
| # list of 1s and 0s, coming from check_disabled() | |
| sub anyof { | |
| my $x = 0; | |
| foreach (@_) { $x += $_ } | |
| return $x > 0; | |
| } | |
| # args | |
| # list of 1s and 0s, coming from check_disabled() | |
| sub allof { | |
| my $x = 1; | |
| foreach (@_) { $x *= $_ } | |
| return $x > 0; | |
| } | |
| # args | |
| # list of strings, all of them should be names of features | |
| # that can be disabled. | |
| # returns a list of 1s (if the corresponding feature is disabled) | |
| # and 0s (if it isn't) | |
| sub check_disabled { | |
| return map { exists $disabled{lc $_} ? 1 : 0 } @_; | |
| } | |
| # Exported functions ################################################# | |
| # args: | |
| # list of features to check | |
| sub anydisabled { | |
| load_configdata() unless $configdata_loaded; | |
| my @ret = check_disabled(@_); | |
| return @ret if wantarray; | |
| return anyof(@ret); | |
| } | |
| # args: | |
| # list of features to check | |
| sub alldisabled { | |
| load_configdata() unless $configdata_loaded; | |
| my @ret = check_disabled(@_); | |
| return @ret if wantarray; | |
| return allof(@ret); | |
| } | |
| # !!! Kept for backward compatibility | |
| # args: | |
| # single string | |
| sub disabled { | |
| anydisabled(@_); | |
| } | |
| sub available_protocols { | |
| load_configdata() unless $configdata_loaded; | |
| my $protocol_class = shift; | |
| if (exists $available_protocols{lc $protocol_class}) { | |
| return @{$available_protocols{lc $protocol_class}} | |
| } | |
| return (); | |
| } | |
| sub config { | |
| return $config{$_[0]}; | |
| } | |
| # IPv4 / IPv6 checker | |
| my $have_IPv4 = -1; | |
| my $have_IPv6 = -1; | |
| my $IP_factory; | |
| sub check_IP { | |
| my $listenaddress = shift; | |
| eval { | |
| require IO::Socket::IP; | |
| my $s = IO::Socket::IP->new( | |
| LocalAddr => $listenaddress, | |
| LocalPort => 0, | |
| Listen=>1, | |
| ); | |
| $s or die "\n"; | |
| $s->close(); | |
| }; | |
| if ($@ eq "") { | |
| return 1; | |
| } | |
| eval { | |
| require IO::Socket::INET6; | |
| my $s = IO::Socket::INET6->new( | |
| LocalAddr => $listenaddress, | |
| LocalPort => 0, | |
| Listen=>1, | |
| ); | |
| $s or die "\n"; | |
| $s->close(); | |
| }; | |
| if ($@ eq "") { | |
| return 1; | |
| } | |
| eval { | |
| require IO::Socket::INET; | |
| my $s = IO::Socket::INET->new( | |
| LocalAddr => $listenaddress, | |
| LocalPort => 0, | |
| Listen=>1, | |
| ); | |
| $s or die "\n"; | |
| $s->close(); | |
| }; | |
| if ($@ eq "") { | |
| return 1; | |
| } | |
| return 0; | |
| } | |
| sub have_IPv4 { | |
| if ($have_IPv4 < 0) { | |
| $have_IPv4 = check_IP("127.0.0.1"); | |
| } | |
| return $have_IPv4; | |
| } | |
| sub have_IPv6 { | |
| if ($have_IPv6 < 0) { | |
| $have_IPv6 = check_IP("::1"); | |
| } | |
| return $have_IPv6; | |
| } | |
| =head1 SEE ALSO | |
| L<OpenSSL::Test> | |
| =head1 AUTHORS | |
| Stephen Henson E<lt>steve@openssl.orgE<gt> and | |
| Richard Levitte E<lt>levitte@openssl.orgE<gt> | |
| =cut | |
| 1; |