[pmg-devel] [PATCH pmg-api 2/2] add PMG::API2::DestinationTLSPolicy

Stoiko Ivanov s.ivanov at proxmox.com
Fri Sep 21 15:51:42 CEST 2018


to handle /etc/pmg/tls_policy via API, using PMG::API2::Transport
as base/inspiration.

This enables PMG to enforce TLS on a per-domain basis.
See http://www.postfix.org/postconf.5.html#smtp_tls_policy_maps and
http://www.postfix.org/TLS_README.html#client_tls_policy for reference.

Signed-off-by: Stoiko Ivanov <s.ivanov at proxmox.com>
---
 Makefile                         |   1 +
 PMG/API2/Config.pm               |   7 ++
 PMG/API2/DestinationTLSPolicy.pm | 214 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 222 insertions(+)
 create mode 100644 PMG/API2/DestinationTLSPolicy.pm

diff --git a/Makefile b/Makefile
index 4346e37..53d97fd 100644
--- a/Makefile
+++ b/Makefile
@@ -123,6 +123,7 @@ LIBSOURCES =				\
 	PMG/API2/Services.pm		\
 	PMG/API2/Tasks.pm		\
 	PMG/API2/LDAP.pm		\
+	PMG/API2/DestinationTLSPolicy.pm\
 	PMG/API2/Domains.pm		\
 	PMG/API2/Fetchmail.pm		\
 	PMG/API2/Users.pm		\
diff --git a/PMG/API2/Config.pm b/PMG/API2/Config.pm
index e0bf2c1..3b688fa 100644
--- a/PMG/API2/Config.pm
+++ b/PMG/API2/Config.pm
@@ -22,6 +22,7 @@ use PMG::API2::MyNetworks;
 use PMG::API2::SMTPWhitelist;
 use PMG::API2::MimeTypes;
 use PMG::API2::Fetchmail;
+use PMG::API2::DestinationTLSPolicy;
 
 use base qw(PVE::RESTHandler);
 
@@ -76,6 +77,11 @@ __PACKAGE__->register_method ({
 });
 
 __PACKAGE__->register_method ({
+    subclass => "PMG::API2::DestinationTLSPolicy",
+    path => 'tlspolicy',
+});
+
+__PACKAGE__->register_method ({
     name => 'index', 
     path => '',
     method => 'GET',
@@ -111,6 +117,7 @@ __PACKAGE__->register_method ({
 	push @$res, { section => 'transport' };
 	push @$res, { section => 'whitelist' };
 	push @$res, { section => 'regextest' };
+	push @$res, { section => 'tlspolicy' };
 
 	return $res;
     }});
diff --git a/PMG/API2/DestinationTLSPolicy.pm b/PMG/API2/DestinationTLSPolicy.pm
new file mode 100644
index 0000000..4c1ab56
--- /dev/null
+++ b/PMG/API2/DestinationTLSPolicy.pm
@@ -0,0 +1,214 @@
+package PMG::API2::DestinationTLSPolicy;
+
+use strict;
+use warnings;
+
+use PVE::RESTHandler;
+use PVE::INotify;
+use PVE::Exception qw(raise_param_exc);
+
+use PMG::Config;
+
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method ({
+    name => 'index',
+    path => '',
+    method => 'GET',
+    description => "List tls_policy entries.",
+    proxyto => 'master',
+    permissions => { check => [ 'admin', 'audit' ] },
+    parameters => {
+	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => 'object',
+	    properties => {
+		domain => { type => 'string', format => 'transport-domain'},
+		policy => { type => 'string', format => 'tls-policy'},
+	    },
+	},
+	links => [ { rel => 'child', href => "{domain}" } ],
+    },
+    code => sub {
+	my ($param) = @_;
+
+	my $res = [];
+
+	my $policies = PVE::INotify::read_file('tls_policy');
+	foreach my $policy (sort keys %$policies) {
+	    push @$res, $policies->{$policy};
+	}
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'create',
+    path => '',
+    method => 'POST',
+    proxyto => 'master',
+    protected => 1,
+    permissions => { check => [ 'admin' ] },
+    description => "Add tls_policy entry.",
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    domain => {
+		description => "Domain name.",
+		type => 'string', format => 'transport-domain',
+	    },
+	    policy => {
+		description => "TLS policy",
+		type => 'string', format => 'tls-policy',
+	    },
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+	my $domain = $param->{domain};
+
+	my $code = sub {
+	    my $tls_policy = PVE::INotify::read_file('tls_policy');
+	    raise_param_exc({ domain => "DestinationTLSPolicy entry for '$domain' already exists" })
+		if $tls_policy->{$domain};
+
+	    $tls_policy->{$domain} = {
+		domain => $domain,
+		policy => $param->{policy},
+	    };
+
+	    PVE::INotify::write_file('tls_policy', $tls_policy);
+	    PMG::Config::postmap_tls_policy();
+	};
+
+	PMG::Config::lock_config($code, "add tls_policy entry failed");
+
+	return undef;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'read',
+    path => '{domain}',
+    method => 'GET',
+    description => "Read tls_policy entry.",
+    proxyto => 'master',
+    permissions => { check => [ 'admin', 'audit' ] },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    domain => {
+		description => "Domain name.",
+		type => 'string', format => 'transport-domain',
+	    },
+	},
+    },
+    returns => {
+	type => "object",
+	properties => {
+	    domain => { type => 'string', format => 'transport-domain'},
+	    policy => { type => 'string', format => 'tls-policy'},
+	},
+    },
+    code => sub {
+	my ($param) = @_;
+	my $domain = $param->{domain};
+
+	my $tls_policy = PVE::INotify::read_file('tls_policy');
+
+	if (my $entry = $tls_policy->{$domain}) {
+	    return $entry;
+	}
+
+	raise_param_exc({ domain => "DestinationTLSPolicy entry for '$domain' does not exist" });
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'write',
+    path => '{domain}',
+    method => 'PUT',
+    description => "Update tls_policy entry.",
+    protected => 1,
+    permissions => { check => [ 'admin' ] },
+    proxyto => 'master',
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    domain => {
+		description => "Domain name.",
+		type => 'string', format => 'transport-domain',
+	    },
+	    policy => {
+		description => "TLS policy",
+		type => 'string', format => 'tls-policy',
+	    },
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+	my $domain = $param->{domain};
+	my $policy = $param->{policy};
+
+	my $code = sub {
+
+	    my $tls_policy = PVE::INotify::read_file('tls_policy');
+
+	    raise_param_exc({ domain => "DestinationTLSPolicy entry for '$domain' does not exist" })
+		if !$tls_policy->{$domain};
+
+	    $tls_policy->{$domain}->{policy} = $policy;
+
+	    PVE::INotify::write_file('tls_policy', $tls_policy);
+	    PMG::Config::postmap_tls_policy();
+	};
+
+	PMG::Config::lock_config($code, "update tls_policy entry failed");
+
+	return undef;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'delete',
+    path => '{domain}',
+    method => 'DELETE',
+    description => "Delete a tls_policy entry",
+    protected => 1,
+    permissions => { check => [ 'admin' ] },
+    proxyto => 'master',
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    domain => {
+		description => "Domain name.",
+		type => 'string', format => 'transport-domain',
+	    },
+	}
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+	my $domain = $param->{domain};
+
+	my $code = sub {
+	    my $tls_policy = PVE::INotify::read_file('tls_policy');
+
+	    raise_param_exc({ domain => "DestinationTLSPolicy entry for '$domain' does not exist" })
+		if !$tls_policy->{$domain};
+
+	    delete $tls_policy->{$domain};
+
+	    PVE::INotify::write_file('tls_policy', $tls_policy);
+	    PMG::Config::postmap_tls_policy();
+	};
+
+	PMG::Config::lock_config($code, "delete tls_policy entry failed");
+
+	return undef;
+    }});
+
+1;
-- 
2.11.0




More information about the pmg-devel mailing list