PVE-specific certificate helper functions

Signed-off-by: Fabian Grünbichler <f.gruenbich...@proxmox.com>
---
 PVE/Makefile       |   1 +
 PVE/CertHelpers.pm | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)
 create mode 100644 PVE/CertHelpers.pm

diff --git a/PVE/Makefile b/PVE/Makefile
index 5cc19904..395faf8a 100644
--- a/PVE/Makefile
+++ b/PVE/Makefile
@@ -3,6 +3,7 @@ include ../defines.mk
 SUBDIRS=API2 Status CLI Service
 
 PERLSOURCE =                   \
+       CertHelpers.pm          \
        API2.pm                 \
        API2Tools.pm            \
        HTTPServer.pm           \
diff --git a/PVE/CertHelpers.pm b/PVE/CertHelpers.pm
new file mode 100644
index 00000000..52316aa0
--- /dev/null
+++ b/PVE/CertHelpers.pm
@@ -0,0 +1,107 @@
+package PVE::CertHelpers;
+
+use strict;
+use warnings;
+
+use PVE::Certificate;
+use PVE::JSONSchema;
+use PVE::Tools;
+
+my $account_prefix = '/etc/pve/priv/acme';
+
+PVE::JSONSchema::register_standard_option('pve-acme-account-name', {
+    description => 'ACME account config file name.',
+    type => 'string',
+    format => 'pve-configid',
+    format_description => 'name',
+    optional => 1,
+    default => 'default',
+});
+
+PVE::JSONSchema::register_standard_option('pve-acme-account-contact', {
+    type => 'string',
+    format => 'email-list',
+    description => 'Contact email addresses.',
+});
+
+PVE::JSONSchema::register_standard_option('pve-acme-directory-url', {
+    type => 'string',
+    description => 'URL of ACME CA directory endpoint.',
+    pattern => '^https?://.*',
+});
+
+my $local_cert_lock = '/var/lock/pve-certs.lock';
+
+sub cert_path_prefix {
+    my ($node) = @_;
+
+    return "/etc/pve/nodes/${node}/pveproxy-ssl";
+}
+
+sub cert_lock {
+    my ($timeout, $code, @param) = @_;
+
+    return PVE::Tools::lock_file($local_cert_lock, $timeout, $code, @param);
+}
+
+sub set_cert_files {
+    my ($cert, $key, $path_prefix, $force) = @_;
+
+    my ($old_cert, $old_key, $info);
+
+    my $cert_path = "${path_prefix}.pem";
+    my $cert_path_tmp = "${path_prefix}.pem.old";
+    my $key_path = "${path_prefix}.key";
+    my $key_path_tmp = "${path_prefix}.key.old";
+
+    die "Custom certificate file exists but force flag is not set.\n"
+       if !$force && -e $cert_path;
+    die "Custom certificate key file exists but force flag is not set.\n"
+       if !$force && -e $key_path;
+
+    PVE::Tools::file_copy($cert_path, $cert_path_tmp) if -e $cert_path;
+    PVE::Tools::file_copy($key_path, $key_path_tmp) if -e $key_path;
+
+    eval {
+       PVE::Tools::file_set_contents($cert_path, $cert);
+       PVE::Tools::file_set_contents($key_path, $key) if $key;
+       $info = PVE::Certificate::get_certificate_info($cert_path);
+    };
+    my $err = $@;
+
+    if ($err) {
+       if (-e $cert_path_tmp && -e $key_path_tmp) {
+           eval {
+               warn "Attempting to restore old certificate files..\n";
+               PVE::Tools::file_copy($cert_path_tmp, $cert_path);
+               PVE::Tools::file_copy($key_path_tmp, $key_path);
+           };
+           warn "$@\n" if $@;
+       }
+       die "Setting certificate files failed - $err\n"
+    }
+
+    unlink $cert_path_tmp;
+    unlink $key_path_tmp;
+
+    return $info;
+}
+
+sub acme_account_dir {
+    return $account_prefix;
+}
+
+sub list_acme_accounts {
+    my $accounts = [];
+
+    return $accounts if ! -d $account_prefix;
+
+    PVE::Tools::dir_glob_foreach($account_prefix, qr/[^.]+.*/, sub {
+       my ($name) = @_;
+
+       push @$accounts, $name
+           if PVE::JSONSchema::pve_verify_configid($name, 1);
+    });
+
+    return $accounts;
+}
-- 
2.14.2


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to