From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <c.heiss@proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by lists.proxmox.com (Postfix) with ESMTPS id A08ED91DA6
 for <pmg-devel@lists.proxmox.com>; Mon, 20 Mar 2023 11:36:33 +0100 (CET)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
 by firstgate.proxmox.com (Proxmox) with ESMTP id 827BB28F4
 for <pmg-devel@lists.proxmox.com>; Mon, 20 Mar 2023 11:36:03 +0100 (CET)
Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com
 [94.136.29.106])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by firstgate.proxmox.com (Proxmox) with ESMTPS
 for <pmg-devel@lists.proxmox.com>; Mon, 20 Mar 2023 11:36:02 +0100 (CET)
Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1])
 by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 2EA3E45A3D
 for <pmg-devel@lists.proxmox.com>; Mon, 20 Mar 2023 11:36:02 +0100 (CET)
From: Christoph Heiss <c.heiss@proxmox.com>
To: pmg-devel@lists.proxmox.com
Date: Mon, 20 Mar 2023 11:35:46 +0100
Message-Id: <20230320103548.382757-3-c.heiss@proxmox.com>
X-Mailer: git-send-email 2.39.2
In-Reply-To: <20230320103548.382757-1-c.heiss@proxmox.com>
References: <20230320103548.382757-1-c.heiss@proxmox.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-SPAM-LEVEL: Spam detection results:  0
 AWL -0.069 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pmg-devel] [PATCH v2 pmg-api 2/4] fix #2437: api: Add endpoint for
 managing tls_inbound_domains entries
X-BeenThere: pmg-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox Mail Gateway development discussion
 <pmg-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pmg-devel>, 
 <mailto:pmg-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pmg-devel/>
List-Post: <mailto:pmg-devel@lists.proxmox.com>
List-Help: <mailto:pmg-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pmg-devel>, 
 <mailto:pmg-devel-request@lists.proxmox.com?subject=subscribe>
X-List-Received-Date: Mon, 20 Mar 2023 10:36:33 -0000

Add a new API endpoint `/config/tlsinbounddomains` for managing entries
of the `tls_inbound_domains` postfix map. Modelled after the
`DestinationTLSPolicy` implementation.

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Changes v1 -> v2:
 * New patch; split out from patch #1

 src/Makefile                      |   1 +
 src/PMG/API2/Config.pm            |   7 ++
 src/PMG/API2/InboundTLSDomains.pm | 127 ++++++++++++++++++++++++++++++
 3 files changed, 135 insertions(+)
 create mode 100644 src/PMG/API2/InboundTLSDomains.pm

diff --git a/src/Makefile b/src/Makefile
index 0b424e9..32eac57 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -132,6 +132,7 @@ LIBSOURCES =				\
 	PMG/API2/DKIMSignDomains.pm	\
 	PMG/API2/DKIMSign.pm		\
 	PMG/API2/Fetchmail.pm		\
+	PMG/API2/InboundTLSDomains.pm	\
 	PMG/API2/Users.pm		\
 	PMG/API2/Transport.pm		\
 	PMG/API2/MyNetworks.pm		\
diff --git a/src/PMG/API2/Config.pm b/src/PMG/API2/Config.pm
index 37da096..c71432a 100644
--- a/src/PMG/API2/Config.pm
+++ b/src/PMG/API2/Config.pm
@@ -23,6 +23,7 @@ use PMG::API2::SMTPWhitelist;
 use PMG::API2::MimeTypes;
 use PMG::API2::Fetchmail;
 use PMG::API2::DestinationTLSPolicy;
+use PMG::API2::InboundTLSDomains;
 use PMG::API2::DKIMSign;
 use PMG::API2::SACustom;
 use PMG::API2::PBS::Remote;
@@ -86,6 +87,11 @@ __PACKAGE__->register_method ({
     path => 'tlspolicy',
 });

+__PACKAGE__->register_method ({
+    subclass => "PMG::API2::InboundTLSDomains",
+    path => 'tlsinbounddomains',
+});
+
 __PACKAGE__->register_method({
     subclass => "PMG::API2::DKIMSign",
     path => 'dkim',
@@ -146,6 +152,7 @@ __PACKAGE__->register_method ({
 	push @$res, { section => 'ruledb' };
 	push @$res, { section => 'tfa' };
 	push @$res, { section => 'tlspolicy' };
+	push @$res, { section => 'tlsinbounddomains' };
 	push @$res, { section => 'transport' };
 	push @$res, { section => 'users' };
 	push @$res, { section => 'whitelist' };
diff --git a/src/PMG/API2/InboundTLSDomains.pm b/src/PMG/API2/InboundTLSDomains.pm
new file mode 100644
index 0000000..38bebca
--- /dev/null
+++ b/src/PMG/API2/InboundTLSDomains.pm
@@ -0,0 +1,127 @@
+package PMG::API2::InboundTLSDomains;
+
+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_inbound_domains entries.',
+    proxyto => 'master',
+    permissions => { check => [ 'admin', 'audit' ] },
+    parameters => {
+	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => 'string',
+	    format => 'transport-domain',
+	},
+	description => 'List of domains for which TLS will be enforced on incoming connections',
+	links => [ { rel => 'child', href => '{domain}' } ],
+    },
+    code => sub {
+	my ($param) = @_;
+
+	my $res = [];
+
+	my $domains = PVE::INotify::read_file('tls_inbound_domains');
+
+	foreach my $domain (sort keys %$domains) {
+	    push @$res, { domain => $domain };
+	}
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'create',
+    path => '',
+    method => 'POST',
+    proxyto => 'master',
+    protected => 1,
+    permissions => { check => [ 'admin' ] },
+    description => 'Add new tls_inbound_domains entry.',
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    domain => {
+		type => 'string',
+		format => 'transport-domain',
+		description => 'Domain for which TLS should be enforced on incoming connections',
+	    },
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+	my $domain = $param->{domain};
+
+	my $code = sub {
+	    my $domains = PVE::INotify::read_file('tls_inbound_domains');
+	    raise_param_exc({ domain => "InboundTLSDomains entry for '$domain' already exists" })
+		if $domains->{$domain};
+
+	    $domains->{$domain} = 1;
+
+	    PVE::INotify::write_file('tls_inbound_domains', $domains);
+	    PMG::Config::postmap_tls_inbound_domains();
+	};
+
+	PMG::Config::lock_config($code, 'adding tls_inbound_domains entry failed');
+
+	return undef;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'delete',
+    path => '{domain}',
+    method => 'DELETE',
+    description => 'Delete a tls_inbound_domains entry',
+    protected => 1,
+    permissions => { check => [ 'admin' ] },
+    proxyto => 'master',
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    domain => {
+		type => 'string',
+		format => 'transport-domain',
+		description => 'Domain which should be removed from tls_inbound_domains',
+	    },
+	}
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+	my $domain = $param->{domain};
+
+	my $code = sub {
+	    my $domains = PVE::INotify::read_file('tls_inbound_domains');
+
+	    raise_param_exc({ domain => "tls_inbound_domains entry for '$domain' does not exist" })
+		if !$domains->{$domain};
+
+	    delete $domains->{$domain};
+
+	    PVE::INotify::write_file('tls_inbound_domains', $domains);
+	    PMG::Config::postmap_tls_inbound_domains();
+	};
+
+	PMG::Config::lock_config($code, 'deleting tls_inbound_domains entry failed');
+
+	return undef;
+    }});
+
+1;
--
2.39.2