From: Dietmar Maurer Date: Fri, 25 Nov 2016 06:24:25 +0000 (+0100) Subject: moved x509 certificate cache helpers from pve-manager package X-Git-Url: https://git.proxmox.com/?p=pve-cluster.git;a=commitdiff_plain;h=26784563f32ffc8797019f67993d4fe163027dbd moved x509 certificate cache helpers from pve-manager package No we depend on libcrypt-ssleay-perl. --- diff --git a/data/PVE/Cluster.pm b/data/PVE/Cluster.pm index 3d7f6a3..3ff39aa 100644 --- a/data/PVE/Cluster.pm +++ b/data/PVE/Cluster.pm @@ -11,6 +11,7 @@ use MIME::Base64; use XML::Parser; use Digest::SHA; use Digest::HMAC_SHA1; +use Net::SSLeay; use PVE::Tools; use PVE::INotify; use PVE::IPCC; @@ -1596,6 +1597,102 @@ sub check_corosync_conf_exists { return $exists; } +# X509 Certificate cache helper + +my $cert_cache_nodes = {}; +my $cert_cache_timestamp = time(); +my $cert_cache_fingerprints = {}; + +sub update_cert_cache { + my ($update_node, $clear) = @_; + + syslog('info', "Clearing outdated entries from certificate cache") + if $clear; + + $cert_cache_timestamp = time() if !defined($update_node); + + my $node_list = defined($update_node) ? + [ $update_node ] : [ keys %$cert_cache_nodes ]; + + foreach my $node (@$node_list) { + my $clear_old = sub { + if (my $old_fp = $cert_cache_nodes->{$node}) { + # distrust old fingerprint + delete $cert_cache_fingerprints->{$old_fp}; + # ensure reload on next proxied request + delete $cert_cache_nodes->{$node}; + } + }; + + my $cert_path = "/etc/pve/nodes/$node/pve-ssl.pem"; + my $custom_cert_path = "/etc/pve/nodes/$node/pveproxy-ssl.pem"; + + $cert_path = $custom_cert_path if -f $custom_cert_path; + + my $cert; + eval { + my $bio = Net::SSLeay::BIO_new_file($cert_path, 'r'); + $cert = Net::SSLeay::PEM_read_bio_X509($bio); + Net::SSLeay::BIO_free($bio); + }; + my $err = $@; + if ($err || !defined($cert)) { + &$clear_old() if $clear; + next; + } + + my $fp; + eval { + $fp = Net::SSLeay::X509_get_fingerprint($cert, 'sha256'); + }; + $err = $@; + if ($err || !defined($fp) || $fp eq '') { + &$clear_old() if $clear; + next; + } + + my $old_fp = $cert_cache_nodes->{$node}; + $cert_cache_fingerprints->{$fp} = 1; + $cert_cache_nodes->{$node} = $fp; + + if (defined($old_fp) && $fp ne $old_fp) { + delete $cert_cache_fingerprints->{$old_fp}; + } + } +} + +sub check_cert_fingerprint { + my ($cert) = @_; + + # clear cache every 30 minutes at least + update_cert_cache(undef, 1) if time() - $cert_cache_timestamp >= 60*30; + + # get fingerprint of server certificate + my $fp; + eval { + $fp = Net::SSLeay::X509_get_fingerprint($cert, 'sha256'); + }; + return 0 if $@ || !defined($fp) || $fp eq ''; # error + + my $check = sub { + for my $expected (keys %$cert_cache_fingerprints) { + return 1 if $fp eq $expected; + } + return 0; + }; + + return 1 if &$check(); + + # clear cache and retry at most once every minute + if (time() - $cert_cache_timestamp >= 60) { + syslog ('info', "Could not verify remote node certificate '$fp' with list of pinned certificates, refreshing cache"); + update_cert_cache(); + return &$check(); + } + + return 0; +} + # bash completion helpers sub complete_next_vmid { diff --git a/debian/control b/debian/control index c88196e..73a6146 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Standards-Version: 3.7.3 Package: pve-cluster Architecture: any Pre-Depends: ${misc:Pre-Depends} -Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, perlapi-5.20.0, rsync, libsqlite3-0, sqlite3, libfuse2 (>= 2.9.2-4), fuse, corosync-pve (>= 2.3.4-1), libqb0 (>= 0.17.1-1), libpve-common-perl, libglib2.0-0 (>= 2.42.1-1), rsyslog, openssl, librrd4, librrds-perl, rrdcached, libdigest-hmac-perl, libxml-parser-perl, systemd, faketime +Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, perlapi-5.20.0, rsync, libsqlite3-0, sqlite3, libfuse2 (>= 2.9.2-4), fuse, corosync-pve (>= 2.3.4-1), libqb0 (>= 0.17.1-1), libpve-common-perl, libglib2.0-0 (>= 2.42.1-1), rsyslog, openssl, librrd4, librrds-perl, rrdcached, libdigest-hmac-perl, libxml-parser-perl, systemd, faketime, libcrypt-ssleay-perl Description: Cluster Infrastructure for Proxmox Virtual Environment This package contains the Cluster Infrastructure for the Proxmox Virtual Environment, namely a distributed filesystem to store