add ssl option eval system (#3853)

This commit is contained in:
qgarnier 2022-08-19 15:04:09 +02:00 committed by GitHub
parent f70569a759
commit 0855348c14
4 changed files with 75 additions and 74 deletions

View File

@ -29,6 +29,7 @@ use IO::Socket::INET;
use IO::Socket::SSL;
use Net::SSLeay 1.42;
use DateTime;
use centreon::plugins::misc;
sub new {
my ($class, %options) = @_;
@ -86,13 +87,10 @@ sub check_options {
$self->{output}->option_exit();
}
my $append = '';
foreach (@{$self->{option_results}->{ssl_opt}}) {
if ($_ ne '') {
$self->{ssl_context} .= $append . $_;
$append = ', ';
}
}
$self->{ssl_context} = centreon::plugins::misc::eval_ssl_options(
output => $self->{output},
ssl_opt => $self->{option_results}->{ssl_opt}
);
return 0;
}
@ -190,8 +188,8 @@ sub connect_starttls {
sub get_certificate_informations {
my ($self, %options) = @_;
if (defined($self->{ssl_context}) && $self->{ssl_context} ne '') {
my $context = new IO::Socket::SSL::SSL_Context(eval $self->{ssl_context});
if (scalar(keys %{$self->{ssl_context}}) > 0) {
my $context = new IO::Socket::SSL::SSL_Context(%{$self->{ssl_context}});
eval { IO::Socket::SSL::set_default_context($context) };
if ($@) {
$self->{output}->add_option_msg(short_msg => sprintf("Error setting SSL context: %s", $@));
@ -265,7 +263,7 @@ Examples:
Do not verify certificate: --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"
Verify certificate: --ssl-opt="SSL_verify_mode => SSL_VERIFY_PEER" --ssl-opt="SSL_version => TLSv1"
Verify certificate: --ssl-opt="SSL_verify_mode => SSL_VERIFY_PEER" --ssl-opt="SSL_version => 'TLSv1'"
=item B<--ssl-ignore-errors>

View File

@ -548,6 +548,55 @@ sub uniq {
return grep { !$seen{$_}++ } @_;
}
sub eval_ssl_options {
my (%options) = @_;
my $ssl_context = {};
return $ssl_context if (!defined($options{ssl_opt}));
my ($rv) = centreon::plugins::misc::mymodule_load(
output => $options{output}, module => 'Safe',
no_quit => 1
);
centreon::plugins::misc::mymodule_load(
output => $options{output}, module => 'IO::Socket::SSL',
no_quit => 1
);
my $safe;
if ($rv == 0) {
$safe = Safe->new();
$safe->permit_only(':base_core', 'rv2gv', 'padany');
$safe->share('$values');
$safe->share('$assign_var');
$safe->share_from('IO::Socket::SSL', [
'SSL_VERIFY_NONE', 'SSL_VERIFY_PEER', 'SSL_VERIFY_FAIL_IF_NO_PEER_CERT', 'SSL_VERIFY_CLIENT_ONCE',
'SSL_RECEIVED_SHUTDOWN', 'SSL_SENT_SHUTDOWN',
'SSL_OCSP_NO_STAPLE', 'SSL_OCSP_MUST_STAPLE', 'SSL_OCSP_FAIL_HARD', 'SSL_OCSP_FULL_CHAIN', 'SSL_OCSP_TRY_STAPLE'
]);
}
foreach (@{$options{ssl_opt}}) {
if (/(SSL_[A-Za-z_]+)\s+=>\s*(\S+)/) {
my ($label, $eval) = ($1, $2);
our $assign_var;
if (defined($safe)) {
$safe->reval("\$assign_var = $eval", 1);
if ($@) {
die 'Unsafe code evaluation: ' . $@;
}
} else {
eval "\$assign_var = $eval";
}
$ssl_context->{$label} = $assign_var;
}
}
return $ssl_context;
}
1;
__END__

View File

@ -46,14 +46,14 @@ sub new {
if (!defined($options{noptions})) {
$options{options}->add_options(arguments => {
'nrpe-version:s' => { name => 'nrpe_version', default => 2 },
'nrpe-port:s' => { name => 'nrpe_port', default => 5666 },
'nrpe-payload:s' => { name => 'nrpe_payload', default => 1024 },
'nrpe-bindaddr:s' => { name => 'nrpe_bindaddr' },
'nrpe-use-ipv4' => { name => 'nrpe_use_ipv4' },
'nrpe-use-ipv6' => { name => 'nrpe_use_ipv6' },
'nrpe-timeout:s' => { name => 'nrpe_timeout', default => 10 },
'ssl-opt:s@' => { name => 'ssl_opt' },
'nrpe-version:s' => { name => 'nrpe_version', default => 2 },
'nrpe-port:s' => { name => 'nrpe_port', default => 5666 },
'nrpe-payload:s' => { name => 'nrpe_payload', default => 1024 },
'nrpe-bindaddr:s' => { name => 'nrpe_bindaddr' },
'nrpe-use-ipv4' => { name => 'nrpe_use_ipv4' },
'nrpe-use-ipv6' => { name => 'nrpe_use_ipv6' },
'nrpe-timeout:s' => { name => 'nrpe_timeout', default => 10 },
'ssl-opt:s@' => { name => 'ssl_opt' }
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'NRPE CLASS OPTIONS');
@ -88,59 +88,12 @@ sub check_options {
$self->{nrpe_params}->{Domain} = AF_INET6;
}
$self->{ssl_context} = {};
foreach (@{$options{option_results}->{ssl_opt}}) {
if (/(SSL_[A-Za-z_]+)\s+=>\s*(\S+)/) {
my $value = $2;
$value = $self->assign_eval(eval => $value);
$self->{ssl_context}->{$1} = $value;
}
}
}
sub load_eval {
my ($self) = @_;
my ($code) = centreon::plugins::misc::mymodule_load(
output => $self->{output}, module => 'Safe',
no_quit => 1
$self->{ssl_context} = centreon::plugins::misc::eval_ssl_options(
output => $self->{output},
ssl_opt => $self->{option_results}->{ssl_opt}
);
if ($code == 0) {
$self->{safe} = Safe->new();
$self->{safe}->permit_only(':base_core', 'rv2gv', 'padany');
$self->{safe}->share('$values');
$self->{safe}->share('$assign_var');
$self->{safe}->share_from('IO::Socket::SSL', [
'SSL_VERIFY_NONE', 'SSL_VERIFY_PEER', 'SSL_VERIFY_FAIL_IF_NO_PEER_CERT', 'SSL_VERIFY_CLIENT_ONCE',
'SSL_RECEIVED_SHUTDOWN', 'SSL_SENT_SHUTDOWN',
'SSL_OCSP_NO_STAPLE', 'SSL_OCSP_MUST_STAPLE', 'SSL_OCSP_FAIL_HARD', 'SSL_OCSP_FULL_CHAIN', 'SSL_OCSP_TRY_STAPLE'
]);
}
$self->{safe_test} = 1;
}
sub assign_eval {
my ($self, %options) = @_;
$self->load_eval() if (!defined($self->{safe_test}) || $self->{safe_test} == 0);
our $assign_var;
if (defined($self->{safe})) {
our $values = $options{values};
$self->{safe}->reval("\$assign_var = $options{eval}", 1);
if ($@) {
die 'Unsafe code evaluation: ' . $@;
}
} else {
my $values = $options{values};
eval "\$assign_var = $options{eval}";
}
return $assign_var;
}
sub create_socket {
my ($self, %options) = @_;

View File

@ -26,6 +26,7 @@ use DateTime;
use MongoDB;
use Hash::Ordered;
use URI::Encode;
use centreon::plugins::misc;
sub new {
my ($class, %options) = @_;
@ -83,10 +84,10 @@ sub check_options {
$self->{output}->option_exit();
}
foreach (@{$self->{option_results}->{ssl_opt}}) {
$_ =~ /(\w+)\s*=>\s*(\w+)/;
$self->{ssl_opts}->{$1} = $2;
}
$self->{ssl_opts} = centreon::plugins::misc::eval_ssl_options(
output => $self->{output},
ssl_opt => $self->{option_results}->{ssl_opt}
);
return 0;
}