]>
Commit | Line | Data |
---|---|---|
ccfd6ea6 FG |
1 | package PVE::CertHelpers; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
6 | use PVE::Certificate; | |
7 | use PVE::JSONSchema; | |
8 | use PVE::Tools; | |
9 | ||
10 | my $account_prefix = '/etc/pve/priv/acme'; | |
11 | ||
12 | PVE::JSONSchema::register_standard_option('pve-acme-account-name', { | |
13 | description => 'ACME account config file name.', | |
14 | type => 'string', | |
15 | format => 'pve-configid', | |
16 | format_description => 'name', | |
17 | optional => 1, | |
18 | default => 'default', | |
19 | }); | |
20 | ||
21 | PVE::JSONSchema::register_standard_option('pve-acme-account-contact', { | |
22 | type => 'string', | |
23 | format => 'email-list', | |
24 | description => 'Contact email addresses.', | |
25 | }); | |
26 | ||
27 | PVE::JSONSchema::register_standard_option('pve-acme-directory-url', { | |
28 | type => 'string', | |
29 | description => 'URL of ACME CA directory endpoint.', | |
30 | pattern => '^https?://.*', | |
31 | }); | |
32 | ||
33 | my $local_cert_lock = '/var/lock/pve-certs.lock'; | |
34 | ||
35 | sub cert_path_prefix { | |
36 | my ($node) = @_; | |
37 | ||
38 | return "/etc/pve/nodes/${node}/pveproxy-ssl"; | |
39 | } | |
40 | ||
784a50cc DC |
41 | sub default_cert_path_prefix { |
42 | my ($node) = @_; | |
43 | ||
44 | return "/etc/pve/nodes/${node}/pve-ssl"; | |
45 | } | |
46 | ||
ccfd6ea6 FG |
47 | sub cert_lock { |
48 | my ($timeout, $code, @param) = @_; | |
49 | ||
50 | return PVE::Tools::lock_file($local_cert_lock, $timeout, $code, @param); | |
51 | } | |
52 | ||
53 | sub set_cert_files { | |
54 | my ($cert, $key, $path_prefix, $force) = @_; | |
55 | ||
56 | my ($old_cert, $old_key, $info); | |
57 | ||
58 | my $cert_path = "${path_prefix}.pem"; | |
59 | my $cert_path_tmp = "${path_prefix}.pem.old"; | |
60 | my $key_path = "${path_prefix}.key"; | |
61 | my $key_path_tmp = "${path_prefix}.key.old"; | |
62 | ||
63 | die "Custom certificate file exists but force flag is not set.\n" | |
64 | if !$force && -e $cert_path; | |
65 | die "Custom certificate key file exists but force flag is not set.\n" | |
66 | if !$force && -e $key_path; | |
67 | ||
68 | PVE::Tools::file_copy($cert_path, $cert_path_tmp) if -e $cert_path; | |
69 | PVE::Tools::file_copy($key_path, $key_path_tmp) if -e $key_path; | |
70 | ||
71 | eval { | |
72 | PVE::Tools::file_set_contents($cert_path, $cert); | |
73 | PVE::Tools::file_set_contents($key_path, $key) if $key; | |
74 | $info = PVE::Certificate::get_certificate_info($cert_path); | |
75 | }; | |
76 | my $err = $@; | |
77 | ||
78 | if ($err) { | |
79 | if (-e $cert_path_tmp && -e $key_path_tmp) { | |
80 | eval { | |
81 | warn "Attempting to restore old certificate files..\n"; | |
82 | PVE::Tools::file_copy($cert_path_tmp, $cert_path); | |
83 | PVE::Tools::file_copy($key_path_tmp, $key_path); | |
84 | }; | |
85 | warn "$@\n" if $@; | |
86 | } | |
87 | die "Setting certificate files failed - $err\n" | |
88 | } | |
89 | ||
90 | unlink $cert_path_tmp; | |
91 | unlink $key_path_tmp; | |
92 | ||
93 | return $info; | |
94 | } | |
95 | ||
96 | sub acme_account_dir { | |
97 | return $account_prefix; | |
98 | } | |
99 | ||
100 | sub list_acme_accounts { | |
101 | my $accounts = []; | |
102 | ||
103 | return $accounts if ! -d $account_prefix; | |
104 | ||
105 | PVE::Tools::dir_glob_foreach($account_prefix, qr/[^.]+.*/, sub { | |
106 | my ($name) = @_; | |
107 | ||
108 | push @$accounts, $name | |
109 | if PVE::JSONSchema::pve_verify_configid($name, 1); | |
110 | }); | |
111 | ||
112 | return $accounts; | |
113 | } |