[pve-devel] [PATCH v2 cluster 05/13] move certificate cache to own file
Fabian Grünbichler
f.gruenbichler at proxmox.com
Mon Nov 11 11:27:59 CET 2019
and just keep node to certificate path helper in PVE::Cluster.
Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
Notes:
in peparation of moving it to pve-manager altogether in the next patch
requires versioned breaks on pve-manager (HTTPServer.pm)
data/PVE/Cluster/Makefile | 2 +-
data/PVE/Cluster.pm | 82 -------------------------------
data/PVE/Cluster/CertCache.pm | 92 +++++++++++++++++++++++++++++++++++
3 files changed, 93 insertions(+), 83 deletions(-)
create mode 100644 data/PVE/Cluster/CertCache.pm
diff --git a/data/PVE/Cluster/Makefile b/data/PVE/Cluster/Makefile
index 0b25cfc..ec267a6 100644
--- a/data/PVE/Cluster/Makefile
+++ b/data/PVE/Cluster/Makefile
@@ -1,6 +1,6 @@
PVEDIR=${DESTDIR}/usr/share/perl5/PVE
-SOURCES=IPCConst.pm Setup.pm
+SOURCES=IPCConst.pm Setup.pm CertCache.pm
.PHONY: install
install: ${SOURCES}
diff --git a/data/PVE/Cluster.pm b/data/PVE/Cluster.pm
index b5157ba..5b017e4 100644
--- a/data/PVE/Cluster.pm
+++ b/data/PVE/Cluster.pm
@@ -978,58 +978,6 @@ cfs_register_file('datacenter.cfg',
\&parse_datacenter_config,
\&write_datacenter_config);
-# 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 $fp = eval { get_node_fingerprint($node) };
- if (my $err = $@) {
- warn "$err\n";
- &$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};
- }
- }
-}
-
-# load and cache cert fingerprint once
-sub initialize_cert_cache {
- my ($node) = @_;
-
- update_cert_cache($node)
- if defined($node) && !defined($cert_cache_nodes->{$node});
-}
-
sub get_node_fingerprint {
my ($node) = @_;
@@ -1041,36 +989,6 @@ sub get_node_fingerprint {
return PVE::Certificate::get_certificate_fingerprint($cert_path);
}
-
-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 = 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/data/PVE/Cluster/CertCache.pm b/data/PVE/Cluster/CertCache.pm
new file mode 100644
index 0000000..98d0ed3
--- /dev/null
+++ b/data/PVE/Cluster/CertCache.pm
@@ -0,0 +1,92 @@
+package PVE::Cluster::CertCache;
+
+use strict;
+use warnings;
+
+use Net::SSLeay;
+
+use PVE::Cluster;
+use PVE::SafeSyslog;
+
+# 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 $fp = eval { PVE::Cluster::get_node_fingerprint($node) };
+ if (my $err = $@) {
+ warn "$err\n";
+ &$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};
+ }
+ }
+}
+
+# load and cache cert fingerprint once
+sub initialize_cert_cache {
+ my ($node) = @_;
+
+ update_cert_cache($node)
+ if defined($node) && !defined($cert_cache_nodes->{$node});
+}
+
+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 = 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;
+}
+
+1;
--
2.20.1
More information about the pve-devel
mailing list