]> git.proxmox.com Git - pmg-api.git/commitdiff
fix #1948: allow setting TLS policy for transports
authorStoiko Ivanov <s.ivanov@proxmox.com>
Wed, 18 Mar 2020 10:23:44 +0000 (11:23 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Tue, 24 Mar 2020 12:30:56 +0000 (13:30 +0100)
As described in postfix TLS Readme [0] the key of the tls_policy table need
not be a destination domain - it can also contain an entry from the transport
table.

By adding a new format, which matches the current format of 'transport-domain'
and additionally the possible values for a smtp/lmtp next-hop (see `man smtp`)
users can now also set a stricter tls policy for their configured downstream
servers (e.g. to enforce TLS, or to disable it, if the downstream server's
TLS implementation is broken).

Tested locally by sending mails to a downstream server with policy 'may' set
(STARTTLS is used), and 'none' (mail goes unecrypted) - verified with tcpdump.

If a next-hop is provided it needs to be literally the same entry as present
in the transport table (w/o the 'smtp:' or 'lmtp:inet:' prefix) - i.e.
it is significant if the entry is enclosed in brackets, or if the (defacto
optional) 'ipv6:' prefix is present in the transport entry.

[0] http://www.postfix.org/TLS_README.html#client_tls_policy

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
Reviewed-By: Dominik Csapak <d.csapak@proxmox.com>
src/PMG/API2/DestinationTLSPolicy.pm
src/PMG/Config.pm

index f112d0bff3bbce5b57a1f33d517edb233d9405c0..55512873a452b0e9323cabd99d595812015e7537 100644 (file)
@@ -27,7 +27,7 @@ __PACKAGE__->register_method ({
        items => {
            type => 'object',
            properties => {
-               domain => { type => 'string', format => 'transport-domain'},
+               domain => { type => 'string', format => 'transport-domain-or-nexthop'},
                policy => { type => 'string', format => 'tls-policy'},
            },
        },
@@ -59,7 +59,7 @@ __PACKAGE__->register_method ({
        properties => {
            domain => {
                description => "Domain name.",
-               type => 'string', format => 'transport-domain',
+               type => 'string', format => 'transport-domain-or-nexthop',
            },
            policy => {
                description => "TLS policy",
@@ -104,14 +104,14 @@ __PACKAGE__->register_method ({
        properties => {
            domain => {
                description => "Domain name.",
-               type => 'string', format => 'transport-domain',
+               type => 'string', format => 'transport-domain-or-nexthop',
            },
        },
     },
     returns => {
        type => "object",
        properties => {
-           domain => { type => 'string', format => 'transport-domain'},
+           domain => { type => 'string', format => 'transport-domain-or-nexthop'},
            policy => { type => 'string', format => 'tls-policy'},
        },
     },
@@ -141,7 +141,7 @@ __PACKAGE__->register_method ({
        properties => {
            domain => {
                description => "Domain name.",
-               type => 'string', format => 'transport-domain',
+               type => 'string', format => 'transport-domain-or-nexthop',
            },
            policy => {
                description => "TLS policy",
@@ -186,7 +186,7 @@ __PACKAGE__->register_method ({
        properties => {
            domain => {
                description => "Domain name.",
-               type => 'string', format => 'transport-domain',
+               type => 'string', format => 'transport-domain-or-nexthop',
            },
        }
     },
index 1cd4ac622c7d807b0da259a96194cc5af56d2b21..2c1c9f1d023d1dc770b8bb78ea54a4252d5d7de4 100755 (executable)
@@ -1033,6 +1033,26 @@ sub pmg_verify_tls_policy_strict {
     return $policy;
 }
 
+PVE::JSONSchema::register_format(
+    'transport-domain-or-nexthop', \&pmg_verify_transport_domain_or_nexthop);
+
+sub pmg_verify_transport_domain_or_nexthop {
+    my ($name, $noerr) = @_;
+
+    if (pmg_verify_transport_domain($name, 1)) {
+       return $name;
+    } elsif ($name =~ m/^(\S+)(?::\d+)?$/) {
+       my $nexthop = $1;
+       if ($nexthop =~ m/^\[(.*)\]$/) {
+           $nexthop = $1;
+       }
+       return $name if pmg_verify_transport_address($nexthop, 1);
+    } else {
+          return undef if $noerr;
+          die "value does not look like a valid domain or next-hop\n";
+    }
+}
+
 sub read_tls_policy {
     my ($filename, $fh) = @_;
 
@@ -1054,7 +1074,7 @@ sub read_tls_policy {
            my ($domain, $policy) = ($1, $2);
 
            eval {
-               pmg_verify_transport_domain($domain);
+               pmg_verify_transport_domain_or_nexthop($domain);
                pmg_verify_tls_policy($policy);
            };
            if (my $err = $@) {