From 536e907f55e0405398e70203bc4e1d319162d45b Mon Sep 17 00:00:00 2001
From: Marius Burkard <m.burkard@pixcept.de>
Date: Mon, 15 Jul 2019 18:39:50 +0200
Subject: [PATCH] - implemented per-domain-dkim, including custom selector

---
 install/lib/installer_base.lib.php             | 14 ++++++++++++++
 install/tpl/rspamd_dkim_signing.conf.master    |  5 +++--
 server/lib/classes/system.inc.php              | 18 ++++++++++++++++--
 .../plugins-available/mail_plugin_dkim.inc.php |  5 +++++
 .../postfix_server_plugin.inc.php              | 15 +++++++++++++++
 5 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php
index 7abd315b84..4024e544b7 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -1456,6 +1456,20 @@ class installer_base {
 				}
 			}
 			exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
+			
+			if ( substr($mail_config['dkim_path'], strlen($mail_config['dkim_path'])-1) == '/' ) {
+				$mail_config['dkim_path'] = substr($mail_config['dkim_path'], 0, strlen($mail_config['dkim_path'])-1);
+			}
+			$dkim_domains = $this->db->queryAllRecords('SELECT `dkim_selector`, `domain` FROM `mail_domain` WHERE `dkim` = ? ORDER BY `domain` ASC', 'y');
+			$fpp = fopen('/etc/rspamd/local.d/dkim_domains.map', 'w');
+			$fps = fopen('/etc/rspamd/local.d/dkim_selectors.map', 'w');
+			foreach($dkim_domains as $dkim_domain) {
+				fwrite($fpp, $dkim_domain['domain'] . ' ' . $mail_config['dkim_path'] . '/' . $dkim_domain['domain'] . '.private' . "\n");
+				fwrite($fps, $dkim_domain['domain'] . ' ' . $dkim_domain['dkim_selector']);
+			}
+			fclose($fpp);
+			fclose($fps);
+			unset($dkim_domains);
 		}
 
 		if(is_user('_rspamd') && is_group('amavis')) {
diff --git a/install/tpl/rspamd_dkim_signing.conf.master b/install/tpl/rspamd_dkim_signing.conf.master
index 0e55a7ead2..a27ee78f91 100644
--- a/install/tpl/rspamd_dkim_signing.conf.master
+++ b/install/tpl/rspamd_dkim_signing.conf.master
@@ -1,2 +1,3 @@
-path = "<tmpl_var name='dkim_path'>/$domain.private";
-selector = "default";
\ No newline at end of file
+try_fallback = false;
+path_map = "/etc/rspamd/local.d/dkim_domains.map";
+selector_map = "/etc/rspamd/local.d/dkim_selectors.map";";
\ No newline at end of file
diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php
index 5c277ada1a..304701a5f2 100644
--- a/server/lib/classes/system.inc.php
+++ b/server/lib/classes/system.inc.php
@@ -1535,7 +1535,14 @@ class system{
 		$found = 0;
 		if(is_array($lines)) {
 			foreach($lines as $line) {
-				if($strict == 0) {
+				if($strict == 0 && preg_match('/^REGEX:(.*)$/', $search_pattern)) {
+					if(preg_match(substr($search_pattern, 6), $line)) {
+						$out .= $new_line."\n";
+						$found = 1;
+					} else {
+						$out .= $line;
+					}
+				} elseif($strict == 0) {
 					if(stristr($line, $search_pattern)) {
 						$out .= $new_line."\n";
 						$found = 1;
@@ -1573,7 +1580,14 @@ class system{
 		if($lines = @file($filename)) {
 			$out = '';
 			foreach($lines as $line) {
-				if($strict == 0) {
+				if($strict == 0 && preg_match('/^REGEX:(.*)$/', $search_pattern)) {
+					if(preg_match(substr($search_pattern, 6), $line)) {
+						$out .= $new_line."\n";
+						$found = 1;
+					} else {
+						$out .= $line;
+					}
+				} elseif($strict == 0) {
 					if(!stristr($line, $search_pattern)) {
 						$out .= $line;
 					}
diff --git a/server/plugins-available/mail_plugin_dkim.inc.php b/server/plugins-available/mail_plugin_dkim.inc.php
index ff649971a9..ebfd6c0ac7 100755
--- a/server/plugins-available/mail_plugin_dkim.inc.php
+++ b/server/plugins-available/mail_plugin_dkim.inc.php
@@ -347,6 +347,9 @@ class mail_plugin_dkim {
 			}
 			if ($this->write_dkim_key($mail_config['dkim_path']."/".$data['new']['domain'], $data['new']['dkim_private'], $data['new']['domain'])) {
 				if($mail_config['content_filter'] == 'rspamd') {
+					$app->system->replaceLine('/etc/rspamd/local.d/dkim_domains.map', 'REGEX:/^' . preg_quote($data['new']['domain'], '/') . ' /', $data['new']['domain'] . ' ' . $mail_config['dkim_path']."/".$data['new']['domain'] . '.private');
+					$app->system->replaceLine('/etc/rspamd/local.d/dkim_selectors.map', 'REGEX:/^' . preg_quote($data['new']['domain'], '/') . ' /', $data['new']['domain'] . ' ' . $data['new']['dkim_selector']);
+					
 					$app->services->restartServiceDelayed('rspamd', 'reload');
 				} elseif ($this->add_to_amavis($data['new']['domain'], $data['new']['dkim_selector'], $data['old']['dkim_selector'] )) {
 					$this->restart_amavis();
@@ -373,6 +376,8 @@ class mail_plugin_dkim {
 		$this->remove_dkim_key($mail_config['dkim_path']."/".$_data['domain'], $_data['domain']);
 		
 		if($mail_config['content_filter'] == 'rspamd') {
+			$app->system->removeLine('/etc/rspamd/local.d/dkim_domains.map', 'REGEX:/^' . preg_quote($_data['domain'], '/') . ' /');
+			$app->system->removeLine('/etc/rspamd/local.d/dkim_selectors.map', 'REGEX:/^' . preg_quote($_data['domain'], '/') . ' /');
 			$app->services->restartServiceDelayed('rspamd', 'reload');
 		} elseif ($this->remove_from_amavis($_data['domain'])) {
 			$this->restart_amavis();
diff --git a/server/plugins-available/postfix_server_plugin.inc.php b/server/plugins-available/postfix_server_plugin.inc.php
index 763a89b4b4..933db86b3b 100644
--- a/server/plugins-available/postfix_server_plugin.inc.php
+++ b/server/plugins-available/postfix_server_plugin.inc.php
@@ -200,6 +200,21 @@ class postfix_server_plugin {
 					}
 				}
 				exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
+				
+				// get all domains that have dkim enabled
+				if ( substr($mail_config['dkim_path'], strlen($mail_config['dkim_path'])-1) == '/' ) {
+					$mail_config['dkim_path'] = substr($mail_config['dkim_path'], 0, strlen($mail_config['dkim_path'])-1);
+				}
+				$dkim_domains = $app->db->queryAllRecords('SELECT `dkim_selector`, `domain` FROM `mail_domain` WHERE `dkim` = ? ORDER BY `domain` ASC', 'y');
+				$fpp = fopen('/etc/rspamd/local.d/dkim_domains.map', 'w');
+				$fps = fopen('/etc/rspamd/local.d/dkim_selectors.map', 'w');
+				foreach($dkim_domains as $dkim_domain) {
+					fwrite($fpp, $dkim_domain['domain'] . ' ' . $mail_config['dkim_path'] . '/' . $dkim_domain['domain'] . '.private' . "\n");
+					fwrite($fps, $dkim_domain['domain'] . ' ' . $dkim_domain['dkim_selector']);
+				}
+				fclose($fpp);
+				fclose($fps);
+				unset($dkim_domains);
 			}	
 			if($mail_config['content_filter'] == 'amavisd'){
 				exec("postconf -X 'smtpd_milters'");
-- 
GitLab