From e178ca36de6960de3979b66ac99373675f3f9f9d Mon Sep 17 00:00:00 2001
From: Michael Kuron <mkuron@users.noreply.github.com>
Date: Sun, 27 Aug 2017 13:45:18 +0200
Subject: [PATCH 1/4] Rspamd user settings: make regexes case-insensitive

This is necessary because the user web UI normalizes to lowercase
---
 data/conf/rspamd/dynmaps/settings.php | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/data/conf/rspamd/dynmaps/settings.php b/data/conf/rspamd/dynmaps/settings.php
index 23052d3f..5689ece3 100644
--- a/data/conf/rspamd/dynmaps/settings.php
+++ b/data/conf/rspamd/dynmaps/settings.php
@@ -47,7 +47,7 @@ function ucl_rcpts($object, $type) {
       $local = parse_email($row['address'])['local'];
       $domain = parse_email($row['address'])['domain'];
       if (!empty($local) && !empty($domain)) {
-        $rcpt[] = '/' . $local . '\+.*' . $domain . '/';
+        $rcpt[] = '/' . $local . '\+.*' . $domain . '/i';
       }
       $rcpt[] = $row['address'];
     }
@@ -65,7 +65,7 @@ function ucl_rcpts($object, $type) {
         $local = parse_email($row['alias'])['local'];
         $domain = parse_email($row['alias'])['domain'];
         if (!empty($local) && !empty($domain)) {
-          $rcpt[] = '/' . $local . '\+.*' . $domain . '/';
+          $rcpt[] = '/' . $local . '\+.*' . $domain . '/i';
         }
       $rcpt[] = $row['alias'];
       }
@@ -74,20 +74,20 @@ function ucl_rcpts($object, $type) {
     $local = parse_email($row['object'])['local'];
     $domain = parse_email($row['object'])['domain'];
     if (!empty($local) && !empty($domain)) {
-      $rcpt[] = '/' . $local . '\+.*' . $domain . '/';
+      $rcpt[] = '/' . $local . '\+.*' . $domain . '/i';
     }
     $rcpt[] = $object;
   }
   elseif ($type == 'domain') {
     // Domain self
-		$rcpt[] = '/.*@' . $object . '/';
+		$rcpt[] = '/.*@' . $object . '/i';
 		$stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain`
 			WHERE `target_domain` = :object");
 		$stmt->execute(array(':object' => $row['object']));
 		$alias_domains = $stmt->fetchAll(PDO::FETCH_ASSOC);
 		array_filter($alias_domains);
 		while ($row = array_shift($alias_domains)) {
-      $rcpt[] = '/.*@' . $row['alias_domain'] . '/';
+      $rcpt[] = '/.*@' . $row['alias_domain'] . '/i';
 		}
   }
   if (!empty($rcpt)) {
@@ -152,7 +152,7 @@ while ($row = array_shift($rows)) {
 	$grouped_lists = $stmt->fetchAll(PDO::FETCH_COLUMN);
 	$value_sane = preg_replace("/\.\./", ".", (preg_replace("/\*/", ".*", $grouped_lists[0])));
 ?>
-		from = "/(<?=$value_sane;?>)/";
+		from = "/(<?=$value_sane;?>)/i";
 <?php
 	if (!filter_var(trim($row['object']), FILTER_VALIDATE_EMAIL)) {
 ?>
@@ -203,7 +203,7 @@ while ($row = array_shift($rows)) {
 	$grouped_lists = $stmt->fetchAll(PDO::FETCH_COLUMN);
 	$value_sane = preg_replace("/\.\./", ".", (preg_replace("/\*/", ".*", $grouped_lists[0])));
 ?>
-		from = "/(<?=$value_sane;?>)/";
+		from = "/(<?=$value_sane;?>)/i";
 <?php
 	if (!filter_var(trim($row['object']), FILTER_VALIDATE_EMAIL)) {
 ?>

From 93a092e6273217b4c8d226adea075fbb1168fd0a Mon Sep 17 00:00:00 2001
From: Michael Kuron <mkuron@users.noreply.github.com>
Date: Sun, 27 Aug 2017 13:49:34 +0200
Subject: [PATCH 2/4] Rspamd user settings: also match From header

---
 data/conf/rspamd/dynmaps/settings.php | 82 +++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/data/conf/rspamd/dynmaps/settings.php b/data/conf/rspamd/dynmaps/settings.php
index 5689ece3..56481e5e 100644
--- a/data/conf/rspamd/dynmaps/settings.php
+++ b/data/conf/rspamd/dynmaps/settings.php
@@ -174,6 +174,47 @@ while ($row = array_shift($rows)) {
 <?php
 		}
 	}
+?>
+		apply "default" {
+			MAILCOW_WHITE = -999.0;
+		}
+		symbols [
+			"MAILCOW_WHITE"
+		]
+	}
+	whitelist_header_<?=$username_sane;?> {
+<?php
+	$stmt = $pdo->prepare("SELECT GROUP_CONCAT(REPLACE(`value`, '*', '.*') SEPARATOR '|') AS `value` FROM `filterconf`
+		WHERE `object`= :object
+			AND `option` = 'whitelist_from'");
+	$stmt->execute(array(':object' => $row['object']));
+	$grouped_lists = $stmt->fetchAll(PDO::FETCH_COLUMN);
+	$value_sane = preg_replace("/\.\./", ".", (preg_replace("/\*/", ".*", $grouped_lists[0])));
+?>
+		request_header = {
+			"From" = "/(<?=$value_sane;?>)/i";
+		}
+<?php
+	if (!filter_var(trim($row['object']), FILTER_VALIDATE_EMAIL)) {
+?>
+		priority = 5;
+<?php
+		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+?>
+		rcpt = "<?=$rcpt;?>";
+<?php
+		}
+	}
+	else {
+?>
+		priority = 6;
+<?php
+		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+?>
+		rcpt = "<?=$rcpt;?>";
+<?php
+		}
+	}
 ?>
 		apply "default" {
 			MAILCOW_WHITE = -999.0;
@@ -225,6 +266,47 @@ while ($row = array_shift($rows)) {
 <?php
 		}
 	}
+?>
+		apply "default" {
+			MAILCOW_BLACK = 999.0;
+		}
+		symbols [
+			"MAILCOW_BLACK"
+		]
+	}
+	blacklist_header_<?=$username_sane;?> {
+<?php
+	$stmt = $pdo->prepare("SELECT GROUP_CONCAT(REPLACE(`value`, '*', '.*') SEPARATOR '|') AS `value` FROM `filterconf`
+		WHERE `object`= :object
+			AND `option` = 'blacklist_from'");
+	$stmt->execute(array(':object' => $row['object']));
+	$grouped_lists = $stmt->fetchAll(PDO::FETCH_COLUMN);
+	$value_sane = preg_replace("/\.\./", ".", (preg_replace("/\*/", ".*", $grouped_lists[0])));
+?>
+		request_header = {
+			"From" = "/(<?=$value_sane;?>)/i";
+		}
+<?php
+	if (!filter_var(trim($row['object']), FILTER_VALIDATE_EMAIL)) {
+?>
+		priority = 5;
+<?php
+		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+?>
+		rcpt = "<?=$rcpt;?>";
+<?php
+		}
+	}
+	else {
+?>
+		priority = 6;
+<?php
+		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+?>
+		rcpt = "<?=$rcpt;?>";
+<?php
+		}
+	}
 ?>
 		apply "default" {
 			MAILCOW_BLACK = 999.0;

From fcd8cfa4f49dccefabaf55db6fbfe5285c64f2bd Mon Sep 17 00:00:00 2001
From: Michael Kuron <mkuron@users.noreply.github.com>
Date: Sun, 27 Aug 2017 14:05:38 +0200
Subject: [PATCH 3/4] Rspamd user settings: don't print all email addresses of
 a domain

The ucl_rcpts function can already deal with domains, so lets use this capability.
---
 data/conf/rspamd/dynmaps/settings.php | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/data/conf/rspamd/dynmaps/settings.php b/data/conf/rspamd/dynmaps/settings.php
index 56481e5e..9291a014 100644
--- a/data/conf/rspamd/dynmaps/settings.php
+++ b/data/conf/rspamd/dynmaps/settings.php
@@ -83,7 +83,7 @@ function ucl_rcpts($object, $type) {
 		$rcpt[] = '/.*@' . $object . '/i';
 		$stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain`
 			WHERE `target_domain` = :object");
-		$stmt->execute(array(':object' => $row['object']));
+		$stmt->execute(array(':object' => $object));
 		$alias_domains = $stmt->fetchAll(PDO::FETCH_ASSOC);
 		array_filter($alias_domains);
 		while ($row = array_shift($alias_domains)) {
@@ -112,7 +112,7 @@ while ($row = array_shift($rows)) {
 	score_<?=$username_sane;?> {
 		priority = 4;
 <?php
-  foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+  foreach (ucl_rcpts($row['object'], strpos($row['object'], '@') === FALSE ? 'domain' : 'mailbox') as $rcpt) {
 ?>
 		rcpt = "<?=$rcpt;?>";
 <?php
@@ -158,7 +158,7 @@ while ($row = array_shift($rows)) {
 ?>
 		priority = 5;
 <?php
-		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+		foreach (ucl_rcpts($row['object'], strpos($row['object'], '@') === FALSE ? 'domain' : 'mailbox') as $rcpt) {
 ?>
 		rcpt = "<?=$rcpt;?>";
 <?php
@@ -168,7 +168,7 @@ while ($row = array_shift($rows)) {
 ?>
 		priority = 6;
 <?php
-		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+		foreach (ucl_rcpts($row['object'], strpos($row['object'], '@') === FALSE ? 'domain' : 'mailbox') as $rcpt) {
 ?>
 		rcpt = "<?=$rcpt;?>";
 <?php
@@ -199,7 +199,7 @@ while ($row = array_shift($rows)) {
 ?>
 		priority = 5;
 <?php
-		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+		foreach (ucl_rcpts($row['object'], strpos($row['object'], '@') === FALSE ? 'domain' : 'mailbox') as $rcpt) {
 ?>
 		rcpt = "<?=$rcpt;?>";
 <?php
@@ -209,7 +209,7 @@ while ($row = array_shift($rows)) {
 ?>
 		priority = 6;
 <?php
-		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+		foreach (ucl_rcpts($row['object'], strpos($row['object'], '@') === FALSE ? 'domain' : 'mailbox') as $rcpt) {
 ?>
 		rcpt = "<?=$rcpt;?>";
 <?php
@@ -250,7 +250,7 @@ while ($row = array_shift($rows)) {
 ?>
 		priority = 5;
 <?php
-		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+		foreach (ucl_rcpts($row['object'], strpos($row['object'], '@') === FALSE ? 'domain' : 'mailbox') as $rcpt) {
 ?>
 		rcpt = "<?=$rcpt;?>";
 <?php
@@ -260,7 +260,7 @@ while ($row = array_shift($rows)) {
 ?>
 		priority = 6;
 <?php
-		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+		foreach (ucl_rcpts($row['object'], strpos($row['object'], '@') === FALSE ? 'domain' : 'mailbox') as $rcpt) {
 ?>
 		rcpt = "<?=$rcpt;?>";
 <?php
@@ -291,7 +291,7 @@ while ($row = array_shift($rows)) {
 ?>
 		priority = 5;
 <?php
-		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+		foreach (ucl_rcpts($row['object'], strpos($row['object'], '@') === FALSE ? 'domain' : 'mailbox') as $rcpt) {
 ?>
 		rcpt = "<?=$rcpt;?>";
 <?php
@@ -301,7 +301,7 @@ while ($row = array_shift($rows)) {
 ?>
 		priority = 6;
 <?php
-		foreach (ucl_rcpts($row['object'], 'mailbox') as $rcpt) {
+		foreach (ucl_rcpts($row['object'], strpos($row['object'], '@') === FALSE ? 'domain' : 'mailbox') as $rcpt) {
 ?>
 		rcpt = "<?=$rcpt;?>";
 <?php

From 8383ba5e9ceca7e95be56d6b11205339202b98e3 Mon Sep 17 00:00:00 2001
From: Michael Kuron <mkuron@users.noreply.github.com>
Date: Mon, 28 Aug 2017 20:27:53 +0200
Subject: [PATCH 4/4] Rspamd user settings: fix From header match

The request_header regex appears to not be expected to be encapsulated in slashes and does not seem to accept flags.
---
 data/conf/rspamd/dynmaps/settings.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/data/conf/rspamd/dynmaps/settings.php b/data/conf/rspamd/dynmaps/settings.php
index 9291a014..d6ca8a53 100644
--- a/data/conf/rspamd/dynmaps/settings.php
+++ b/data/conf/rspamd/dynmaps/settings.php
@@ -192,7 +192,7 @@ while ($row = array_shift($rows)) {
 	$value_sane = preg_replace("/\.\./", ".", (preg_replace("/\*/", ".*", $grouped_lists[0])));
 ?>
 		request_header = {
-			"From" = "/(<?=$value_sane;?>)/i";
+			"From" = "(<?=$value_sane;?>)";
 		}
 <?php
 	if (!filter_var(trim($row['object']), FILTER_VALIDATE_EMAIL)) {
@@ -284,7 +284,7 @@ while ($row = array_shift($rows)) {
 	$value_sane = preg_replace("/\.\./", ".", (preg_replace("/\*/", ".*", $grouped_lists[0])));
 ?>
 		request_header = {
-			"From" = "/(<?=$value_sane;?>)/i";
+			"From" = "(<?=$value_sane;?>)";
 		}
 <?php
 	if (!filter_var(trim($row['object']), FILTER_VALIDATE_EMAIL)) {