From 0855348c149a0747d0bde6ee8cc363db90c9d10a Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 19 Aug 2022 15:04:09 +0200 Subject: [PATCH] add ssl option eval system (#3853) --- .../apps/protocols/x509/custom/tcp.pm | 18 ++--- centreon-plugins/centreon/plugins/misc.pm | 49 +++++++++++++ centreon-plugins/centreon/plugins/nrpe.pm | 73 ++++--------------- .../database/mongodb/custom/driver.pm | 9 ++- 4 files changed, 75 insertions(+), 74 deletions(-) diff --git a/centreon-plugins/apps/protocols/x509/custom/tcp.pm b/centreon-plugins/apps/protocols/x509/custom/tcp.pm index 75d31ae2d..63e5b22bd 100644 --- a/centreon-plugins/apps/protocols/x509/custom/tcp.pm +++ b/centreon-plugins/apps/protocols/x509/custom/tcp.pm @@ -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> diff --git a/centreon-plugins/centreon/plugins/misc.pm b/centreon-plugins/centreon/plugins/misc.pm index 411cd5770..6152eff35 100644 --- a/centreon-plugins/centreon/plugins/misc.pm +++ b/centreon-plugins/centreon/plugins/misc.pm @@ -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__ diff --git a/centreon-plugins/centreon/plugins/nrpe.pm b/centreon-plugins/centreon/plugins/nrpe.pm index 6e72e6481..ee3186fef 100644 --- a/centreon-plugins/centreon/plugins/nrpe.pm +++ b/centreon-plugins/centreon/plugins/nrpe.pm @@ -46,26 +46,26 @@ 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'); $self->{output} = $options{output}; - + return $self; } sub check_options { my ($self, %options) = @_; - + $options{option_results}->{nrpe_version} =~ s/^v//; if ($options{option_results}->{nrpe_version} !~ /2|3|4/) { $self->{output}->add_option_msg(short_msg => "Unknown NRPE version."); @@ -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) = @_; diff --git a/centreon-plugins/database/mongodb/custom/driver.pm b/centreon-plugins/database/mongodb/custom/driver.pm index 358cc6282..2472ae411 100644 --- a/centreon-plugins/database/mongodb/custom/driver.pm +++ b/centreon-plugins/database/mongodb/custom/driver.pm @@ -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; }