]> git.proxmox.com Git - pmg-api.git/commitdiff
add DKIM API paths
authorStoiko Ivanov <s.ivanov@proxmox.com>
Mon, 21 Oct 2019 17:23:32 +0000 (19:23 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 23 Oct 2019 09:28:31 +0000 (11:28 +0200)
A new path is added at /config/dkim with 2 subpaths:
* /config/dkim/domains gives access to the dkimdomains
* /config/dkim/selector gives access to the private key for the configured
  selector

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
src/Makefile
src/PMG/API2/Config.pm
src/PMG/API2/DKIMSign.pm [new file with mode: 0644]

index aa8c6447e92c0ddb092cf142828f81dc47cb9192..89658db8c8eb10f093ba8850541874979762dcdd 100644 (file)
@@ -120,6 +120,7 @@ LIBSOURCES =                                \
        PMG/API2/DestinationTLSPolicy.pm\
        PMG/API2/Domains.pm             \
        PMG/API2/DKIMSignDomains.pm     \
+       PMG/API2/DKIMSign.pm            \
        PMG/API2/Fetchmail.pm           \
        PMG/API2/Users.pm               \
        PMG/API2/Transport.pm           \
index 3b688faafbdbd41b4ab50073ca5e0f3e01908600..43653e458d90124a45884048ef9203147740a112 100644 (file)
@@ -23,6 +23,7 @@ use PMG::API2::SMTPWhitelist;
 use PMG::API2::MimeTypes;
 use PMG::API2::Fetchmail;
 use PMG::API2::DestinationTLSPolicy;
+use PMG::API2::DKIMSign;
 
 use base qw(PVE::RESTHandler);
 
@@ -81,6 +82,11 @@ __PACKAGE__->register_method ({
     path => 'tlspolicy',
 });
 
+__PACKAGE__->register_method({
+    subclass => "PMG::API2::DKIMSign",
+    path => 'dkim',
+});
+
 __PACKAGE__->register_method ({
     name => 'index', 
     path => '',
@@ -118,6 +124,7 @@ __PACKAGE__->register_method ({
        push @$res, { section => 'whitelist' };
        push @$res, { section => 'regextest' };
        push @$res, { section => 'tlspolicy' };
+       push @$res, { section => 'dkim' };
 
        return $res;
     }});
diff --git a/src/PMG/API2/DKIMSign.pm b/src/PMG/API2/DKIMSign.pm
new file mode 100644 (file)
index 0000000..8e2d85b
--- /dev/null
@@ -0,0 +1,127 @@
+package PMG::API2::DKIMSign;
+
+use strict;
+use warnings;
+
+use PVE::Tools qw(extract_param);
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::Exception qw(raise_param_exc);
+use PVE::RESTHandler;
+
+use PMG::Config;
+use PMG::DKIMSign;
+
+use PMG::API2::DKIMSignDomains;
+
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method({
+    subclass => "PMG::API2::DKIMSignDomains",
+    path => 'domains',
+});
+
+__PACKAGE__->register_method({
+    name => 'index',
+    path => '',
+    method => 'GET',
+    description => "Directory index.",
+    parameters => {
+       additionalProperties => 0,
+       properties => {},
+    },
+    returns => {
+       type => 'array',
+       items => {
+           type => "object",
+           properties => { section => { type => 'string'} },
+       },
+       links => [ { rel => 'child', href => "{section}" } ],
+    },
+    code => sub {
+       my ($param) = @_;
+
+       return [
+           { section => 'domains'},
+           { section => 'selector'}
+       ];
+    }});
+
+__PACKAGE__->register_method({
+    name => 'set_selector',
+    path => 'selector',
+    method => 'POST',
+    description => "Generate a new private key for selector. All future mail will be signed with the new key!",
+    protected => 1,
+    permissions => { check => [ 'admin' ] },
+    proxyto => 'master',
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           selector => {
+               description => "DKIM Selector",
+               type => 'string', format => 'dns-name',
+           },
+           keysize => {
+               description => "Number of bits for the RSA-Key",
+               type => 'integer', minimum => 1024
+           },
+       },
+    },
+    returns => { type => 'null' },
+    code => sub {
+       my ($param) = @_;
+       my $selector = extract_param($param, 'selector');
+       my $keysize = extract_param($param, 'keysize');
+
+       PMG::DKIMSign::set_selector($selector, $keysize);
+
+       return undef;
+    }});
+
+sub pmg_verify_dkim_pubkey_record {
+    my ($rec, $noerr) = @_;
+
+    if ($rec !~ /\._domainkey\tIN\tTXT\t\( "v=DKIM1; h=sha256; k=rsa; ".+ \)  ; ----- DKIM key/ms ) {
+       return undef if $noerr;
+       die "value does not look like a valid DKIM TXT record\n";
+    }
+
+    return $rec
+}
+
+PVE::JSONSchema::register_format(
+    'pmg-dkim-record', \&pmg_verify_dkim_pubkey_record);
+
+__PACKAGE__->register_method({
+    name => 'get_selector_info',
+    path => 'selector',
+    method => 'GET',
+    description => "Get the public key for the configured selector, prepared as DKIM TXT record",
+    protected => 1,
+    permissions => { check => [ 'admin' ] },
+    proxyto => 'master',
+    parameters => {
+       additionalProperties => 0,
+       properties => { },
+    },
+    returns => {
+       type => 'object',
+       properties => {
+           selector => { type => 'string', format => 'dns-name', optional => 1 },
+           keysize => { type => 'integer', minimum => 1024 , optional => 1},
+           record => { type => 'string', format => 'pmg-dkim-record', optional => 1},
+       },
+    },
+    code => sub {
+       my $cfg = PMG::Config->new();
+       my $selector = $cfg->get('admin', 'dkim_selector');
+
+       return {} if !defined($selector);
+
+       my ($record, $size);
+       eval { ($record, $size) = PMG::DKIMSign::get_selector_info($selector); };
+       return {selector => $selector} if $@;
+
+       return { selector => $selector, keysize => $size, record => $record };
+    }});
+1;