# Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (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 {
    load_configdata() unless $configdata_loaded;
    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;
