From 644487e3d29ac87f520ff846ec64bba0ca4182c6 Mon Sep 17 00:00:00 2001 From: Stoiko Ivanov Date: Wed, 18 Mar 2020 11:23:44 +0100 Subject: [PATCH] fix #1948: allow setting TLS policy for transports 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 Reviewed-By: Dominik Csapak --- src/PMG/API2/DestinationTLSPolicy.pm | 12 ++++++------ src/PMG/Config.pm | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/PMG/API2/DestinationTLSPolicy.pm b/src/PMG/API2/DestinationTLSPolicy.pm index f112d0b..5551287 100644 --- a/src/PMG/API2/DestinationTLSPolicy.pm +++ b/src/PMG/API2/DestinationTLSPolicy.pm @@ -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', }, } }, diff --git a/src/PMG/Config.pm b/src/PMG/Config.pm index 1cd4ac6..2c1c9f1 100755 --- a/src/PMG/Config.pm +++ b/src/PMG/Config.pm @@ -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 = $@) { -- 2.39.2