]> git.proxmox.com Git - pmg-api.git/commitdiff
fix #2504: do not overwrite existing selector key
authorStoiko Ivanov <s.ivanov@proxmox.com>
Tue, 14 Jan 2020 18:31:34 +0000 (19:31 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Tue, 21 Jan 2020 08:08:22 +0000 (09:08 +0100)
This patch changes the behavior of DKIM selector creation. Instead of blindly
overwriting an already present file, add a force parameter to overwrite it (and
behave like the current code).

Overwriting an existing selector can potentially be quite destructive (e.g.
a setup where the admin has already posted the DNS-record for one selector to
many domains, then wants to quickly experiment with a larger keysize, and tries
to go back to the existing behavior).

The new behavior without force set to true, when a private key for the selector
already exists is to die if the file is either not a private RSA key, or has
the wrong size, or else just set the selector in pmg.conf

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
src/PMG/API2/DKIMSign.pm
src/PMG/DKIMSign.pm

index 8e2d85b364d65d7208224666bd397f7c8255dfe0..a8f4bd850208a90c2a212ba17a0b93b622995993 100644 (file)
@@ -65,6 +65,10 @@ __PACKAGE__->register_method({
                description => "Number of bits for the RSA-Key",
                type => 'integer', minimum => 1024
            },
+           force => {
+               description => "Overwrite existing key",
+               type => 'boolean', optional => 1
+           },
        },
     },
     returns => { type => 'null' },
@@ -72,8 +76,9 @@ __PACKAGE__->register_method({
        my ($param) = @_;
        my $selector = extract_param($param, 'selector');
        my $keysize = extract_param($param, 'keysize');
+       my $force = extract_param($param, 'force');
 
-       PMG::DKIMSign::set_selector($selector, $keysize);
+       PMG::DKIMSign::set_selector($selector, $keysize, $force);
 
        return undef;
     }});
index 5810cea339cec7052ff36a2eefa0720c66b56bd7..7cb06a651d87138592fefa6d5b3862bfed5c52df 100644 (file)
@@ -157,22 +157,35 @@ sub get_selector_info {
 }
 
 sub set_selector {
-    my ($selector, $keysize) = @_;
+    my ($selector, $keysize, $force) = @_;
 
     die "no selector provided\n" if !defined($selector);
     die "no keysize provided\n" if !defined($keysize);
     die "invalid keysize\n" if ($keysize < 1024);
     my $privkey_file = "/etc/pmg/dkim/$selector.private";
 
-    my $code = sub{
-       my $cmd = ['openssl', 'genrsa', '-out', $privkey_file, $keysize];
-       PMG::Utils::run_silent_cmd($cmd);
+    my $code = sub {
+       my $genkey = $force || (! -e $privkey_file);
+       if (!$genkey) {
+           my ($privkey, $cursize);
+           eval {
+               my $privkeytext = PVE::Tools::file_get_contents($privkey_file);
+               $privkey =  Crypt::OpenSSL::RSA->new_private_key($privkeytext);
+               $cursize = $privkey->size() * 8;
+           };
+           die "error checking $privkey_file: $@\n" if $@;
+           die "$privkey_file already exists, but has different size ($cursize bits)\n"
+               if $cursize != $keysize;
+       } else {
+           my $cmd = ['openssl', 'genrsa', '-out', $privkey_file, $keysize];
+           PMG::Utils::run_silent_cmd($cmd);
+       }
        my $cfg = PMG::Config->new();
        $cfg->set('admin', 'dkim_selector', $selector);
        $cfg->write();
        PMG::Utils::reload_smtp_filter();
     };
 
-    PMG::Config::lock_config($code, "unable to generate DKIM key ($selector - $keysize bits)");
+    PMG::Config::lock_config($code, "unable to set DKIM key ($selector - $keysize bits)");
 }
 1;