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