Blame util/perl/OpenSSL/Test/Utils.pm

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