[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