[pmg-devel] [PATCH pmg-api v2 3/5] fix #1948: allow setting TLS policy for transports

Stoiko Ivanov s.ivanov at proxmox.com
Wed Mar 18 11:23:44 CET 2020


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 at proxmox.com>
---
 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 9f23970..5be6c46 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.20.1




More information about the pmg-devel mailing list