summaryrefslogtreecommitdiffstats
path: root/test/functional/configs
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/configs')
-rw-r--r--test/functional/configs/arc_signing/redis.conf10
-rw-r--r--test/functional/configs/arc_signing/simple.conf10
-rw-r--r--test/functional/configs/clickhouse-config.xml70
-rw-r--r--test/functional/configs/clickhouse-users.xml109
-rw-r--r--test/functional/configs/clickhouse.conf63
-rw-r--r--test/functional/configs/composites.conf87
-rw-r--r--test/functional/configs/dkim-eddsa.key1
-rw-r--r--test/functional/configs/dkim.conf66
-rw-r--r--test/functional/configs/dkim.key16
-rw-r--r--test/functional/configs/dkim_signing/eddsa.conf8
-rw-r--r--test/functional/configs/dkim_signing/invalidate.conf8
-rw-r--r--test/functional/configs/dkim_signing/milter.conf76
-rw-r--r--test/functional/configs/dkim_signing/multiple.conf17
-rw-r--r--test/functional/configs/dkim_signing/redis.conf10
-rw-r--r--test/functional/configs/dkim_signing/sign_maps.conf11
-rw-r--r--test/functional/configs/dkim_signing/simple.conf9
-rw-r--r--test/functional/configs/dynamic.conf117
-rw-r--r--test/functional/configs/empty.conf0
-rw-r--r--test/functional/configs/force_actions.conf88
-rw-r--r--test/functional/configs/fuzzy-encryption-key.conf2
-rw-r--r--test/functional/configs/fuzzy.conf95
-rw-r--r--test/functional/configs/known_senders-local.conf4
-rw-r--r--test/functional/configs/known_senders.conf7
-rw-r--r--test/functional/configs/loggingtest-local.conf5
-rw-r--r--test/functional/configs/loggingtest.conf3
-rw-r--r--test/functional/configs/lua_script.conf25
-rw-r--r--test/functional/configs/lua_test.conf52
-rw-r--r--test/functional/configs/maps/domains.cdbbin0 -> 2084 bytes
-rw-r--r--test/functional/configs/maps/domains.list5
-rw-r--r--test/functional/configs/maps/domains.list.216
-rw-r--r--test/functional/configs/maps/dynamic_symbols.map2
-rw-r--r--test/functional/configs/maps/external_relay.hostname_map3
-rw-r--r--test/functional/configs/maps/external_relay.ip_map2
-rw-r--r--test/functional/configs/maps/external_relay.user_map2
-rw-r--r--test/functional/configs/maps/external_relay_ip.list1
-rw-r--r--test/functional/configs/maps/ip.list4
-rw-r--r--test/functional/configs/maps/ip2.list3
-rw-r--r--test/functional/configs/maps/known_senders_domains.map2
-rw-r--r--test/functional/configs/maps/map.list3
-rw-r--r--test/functional/configs/maps/mid.list2
-rw-r--r--test/functional/configs/maps/mime_types.wl1
-rw-r--r--test/functional/configs/maps/multiple.list12
-rw-r--r--test/functional/configs/maps/rcvd.list1
-rw-r--r--test/functional/configs/maps/rcvd2.list2
-rw-r--r--test/functional/configs/maps/redir.map3
-rw-r--r--test/functional/configs/maps/regexp.list5
-rw-r--r--test/functional/configs/maps/strict.phishing1
-rw-r--r--test/functional/configs/maps/stricter.phishing1
-rw-r--r--test/functional/configs/maps/top.list2
-rw-r--r--test/functional/configs/maps/url_compose_map.list3
-rw-r--r--test/functional/configs/maps/url_compose_map_for_mails.list3
-rw-r--r--test/functional/configs/maps/users.list1
-rw-r--r--test/functional/configs/maps/utf.list1
-rw-r--r--test/functional/configs/merged-local.conf972
-rw-r--r--test/functional/configs/merged-override.conf435
-rw-r--r--test/functional/configs/merged.conf39
-rw-r--r--test/functional/configs/milter.conf61
-rw-r--r--test/functional/configs/neural.conf83
-rw-r--r--test/functional/configs/neural_noauto.conf85
-rw-r--r--test/functional/configs/nginx.conf20
-rw-r--r--test/functional/configs/p0f.conf13
-rw-r--r--test/functional/configs/password.conf45
-rw-r--r--test/functional/configs/plugins.conf770
-rw-r--r--test/functional/configs/proxy.conf26
-rw-r--r--test/functional/configs/redis-server.conf7
-rw-r--r--test/functional/configs/redis.conf7
-rw-r--r--test/functional/configs/regexp.conf64
-rw-r--r--test/functional/configs/settings.conf117
-rw-r--r--test/functional/configs/spamassassin.conf7
-rw-r--r--test/functional/configs/spamassassin.rules97
-rw-r--r--test/functional/configs/stats.conf85
-rw-r--r--test/functional/configs/trivial.conf50
-rw-r--r--test/functional/configs/url_redirector.conf8
-rw-r--r--test/functional/configs/url_tags.conf9
-rw-r--r--test/functional/configs/whitelist.conf83
75 files changed, 4133 insertions, 0 deletions
diff --git a/test/functional/configs/arc_signing/redis.conf b/test/functional/configs/arc_signing/redis.conf
new file mode 100644
index 0000000..0d049c3
--- /dev/null
+++ b/test/functional/configs/arc_signing/redis.conf
@@ -0,0 +1,10 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+arc {
+ use_redis = true;
+ key_prefix = "TEST_DKIM_KEYS";
+ selector_prefix = "TEST_DKIM_SELECTORS";
+}
+redis {
+ servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}";
+}
diff --git a/test/functional/configs/arc_signing/simple.conf b/test/functional/configs/arc_signing/simple.conf
new file mode 100644
index 0000000..f559e61
--- /dev/null
+++ b/test/functional/configs/arc_signing/simple.conf
@@ -0,0 +1,10 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+arc {
+ path = "{= env.TESTDIR =}/configs/dkim.key";
+ check_pubkey = true;
+ allow_pubkey_mismatch = false;
+ selector = "dkim";
+ use_http_headers = true;
+ allow_headers_fallback = true;
+}
diff --git a/test/functional/configs/clickhouse-config.xml b/test/functional/configs/clickhouse-config.xml
new file mode 100644
index 0000000..3b5c914
--- /dev/null
+++ b/test/functional/configs/clickhouse-config.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<yandex>
+ <logger>
+ <!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger.h#L105 -->
+ <level>debug</level>
+ <log>${RSPAMD_TMPDIR}/clickhouse/clickhouse-server.log</log>
+ <errorlog>${RSPAMD_TMPDIR}/clickhouse/clickhouse-server.err.log</errorlog>
+ <size>1000M</size>
+ <count>10</count>
+ <!-- <console>1</console> --> <!-- Default behavior is autodetection (log to console if not daemon mode and is tty) -->
+ </logger>
+
+ <listen_host>127.0.0.1</listen_host>
+ <http_port>${CLICKHOUSE_PORT}</http_port>
+
+ <!-- Path to configuration file with users, access rights, profiles of settings, quotas. -->
+ <users_config>${RSPAMD_TMPDIR}/users.xml</users_config>
+
+ <!-- <listen_reuse_port>0</listen_reuse_port> -->
+
+ <!-- <listen_backlog>64</listen_backlog> -->
+
+ <max_connections>4096</max_connections>
+ <keep_alive_timeout>3</keep_alive_timeout>
+
+ <!-- Maximum number of concurrent queries. -->
+ <max_concurrent_queries>100</max_concurrent_queries>
+
+ <!-- Set limit on number of open files (default: maximum). This setting makes sense on Mac OS X because getrlimit() fails to retrieve
+ correct maximum value. -->
+ <max_open_files>256</max_open_files>
+
+ <!-- Approximate size of mark cache, used in tables of MergeTree family.
+ In bytes. Cache is single for server. Memory is allocated only on demand.
+ You should not lower this value.
+ -->
+ <mark_cache_size>5368709120</mark_cache_size>
+
+ <!-- Path to data directory, with trailing slash. -->
+ <path>${RSPAMD_TMPDIR}/clickhouse/</path>
+
+ <!-- Default profile of settings. -->
+ <default_profile>default</default_profile>
+
+ <!-- System profile of settings. This settings are used by internal processes (Buffer storage, Distibuted DDL worker and so on). -->
+ <!-- <system_profile>default</system_profile> -->
+
+ <!-- Default database. -->
+ <default_database>default</default_database>
+
+ <!-- Server time zone could be set here.
+
+ Time zone is used when converting between String and DateTime types,
+ when printing DateTime in text formats and parsing DateTime from text,
+ it is used in date and time related functions, if specific time zone was not passed as an argument.
+
+ Time zone is specified as identifier from IANA time zone database, like UTC or Africa/Abidjan.
+ If not specified, system time zone at server startup is used.
+
+ Please note, that server could display time zone alias instead of specified name.
+ Example: W-SU is an alias for Europe/Moscow and Zulu is an alias for UTC.
+ -->
+ <!-- <timezone>Europe/Moscow</timezone> -->
+
+ <!-- You can specify umask here (see "man umask"). Server will apply it on startup.
+ Number is always parsed as octal. Default umask is 027 (other users cannot read logs, data files, etc; group can only read).
+ -->
+ <!-- <umask>022</umask> -->
+
+</yandex>
diff --git a/test/functional/configs/clickhouse-users.xml b/test/functional/configs/clickhouse-users.xml
new file mode 100644
index 0000000..6f746ba
--- /dev/null
+++ b/test/functional/configs/clickhouse-users.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<yandex>
+ <!-- Profiles of settings. -->
+ <profiles>
+ <!-- Default settings. -->
+ <default>
+ <!-- Maximum memory usage for processing single query, in bytes. -->
+ <max_memory_usage>10000000000</max_memory_usage>
+
+ <!-- Use cache of uncompressed blocks of data. Meaningful only for processing many of very short queries. -->
+ <use_uncompressed_cache>0</use_uncompressed_cache>
+
+ <!-- How to choose between replicas during distributed query processing.
+ random - choose random replica from set of replicas with minimum number of errors
+ nearest_hostname - from set of replicas with minimum number of errors, choose replica
+ with minumum number of different symbols between replica's hostname and local hostname
+ (Hamming distance).
+ in_order - first live replica is choosen in specified order.
+ -->
+ <load_balancing>random</load_balancing>
+ </default>
+
+ <!-- Profile that allows only read queries. -->
+ <readonly>
+ <readonly>1</readonly>
+ </readonly>
+ </profiles>
+
+ <!-- Users and ACL. -->
+ <users>
+ <!-- If user name was not specified, 'default' user is used. -->
+ <default>
+ <!-- Password could be specified in plaintext or in SHA256 (in hex format).
+
+ If you want to specify password in plaintext (not recommended), place it in 'password' element.
+ Example: <password>qwerty</password>.
+ Password could be empty.
+
+ If you want to specify SHA256, place it in 'password_sha256_hex' element.
+ Example: <password_sha256_hex>65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5</password_sha256_hex>
+
+ How to generate decent password:
+ Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
+ In first line will be password and in second - corresponding SHA256.
+ -->
+ <password></password>
+
+ <!-- List of networks with open access.
+
+ To open access from everywhere, specify:
+ <ip>::/0</ip>
+
+ To open access only from localhost, specify:
+ <ip>::1</ip>
+ <ip>127.0.0.1</ip>
+
+ Each element of list has one of the following forms:
+ <ip> IP-address or network mask. Examples: 213.180.204.3 or 10.0.0.1/8 or 10.0.0.1/255.255.255.0
+ 2a02:6b8::3 or 2a02:6b8::3/64 or 2a02:6b8::3/ffff:ffff:ffff:ffff::.
+ <host> Hostname. Example: server01.yandex.ru.
+ To check access, DNS query is performed, and all received addresses compared to peer address.
+ <host_regexp> Regular expression for host names. Example, ^server\d\d-\d\d-\d\.yandex\.ru$
+ To check access, DNS PTR query is performed for peer address and then regexp is applied.
+ Then, for result of PTR query, another DNS query is performed and all received addresses compared to peer address.
+ Strongly recommended that regexp is ends with $
+ All results of DNS requests are cached till server restart.
+ -->
+ <networks incl="networks" replace="replace">
+ <ip>::/0</ip>
+ </networks>
+
+ <!-- Settings profile for user. -->
+ <profile>default</profile>
+
+ <!-- Quota for user. -->
+ <quota>default</quota>
+ </default>
+
+ <!-- Example of user with readonly access. -->
+ <readonly>
+ <password></password>
+ <networks incl="networks" replace="replace">
+ <ip>::1</ip>
+ <ip>127.0.0.1</ip>
+ </networks>
+ <profile>readonly</profile>
+ <quota>default</quota>
+ </readonly>
+ </users>
+
+ <!-- Quotas. -->
+ <quotas>
+ <!-- Name of quota. -->
+ <default>
+ <!-- Limits for time interval. You could specify many intervals with different limits. -->
+ <interval>
+ <!-- Length of interval. -->
+ <duration>3600</duration>
+
+ <!-- No limits. Just calculate resource usage for time interval. -->
+ <queries>0</queries>
+ <errors>0</errors>
+ <result_rows>0</result_rows>
+ <read_rows>0</read_rows>
+ <execution_time>0</execution_time>
+ </interval>
+ </default>
+ </quotas>
+</yandex>
diff --git a/test/functional/configs/clickhouse.conf b/test/functional/configs/clickhouse.conf
new file mode 100644
index 0000000..f92f2e7
--- /dev/null
+++ b/test/functional/configs/clickhouse.conf
@@ -0,0 +1,63 @@
+options = {
+ filters = ["spf", "dkim", "regexp"]
+ pidfile = "${RSPAMD_TMPDIR}/rspamd.pid"
+ lua_path = "${INSTALLROOT}/share/rspamd/lib/?.lua"
+ dns {
+ nameserver = ["8.8.8.8", "8.8.4.4"];
+ retransmits = 10;
+ timeout = 2s;
+ fake_records = [{ # ed25519
+ name = "test._domainkey.example.com";
+ type = txt;
+ replies = ["k=ed25519; p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y="];
+ }];
+ }
+}
+clickhouse {
+ # Push update when 1000 records are collected (1000 if unset)
+ limit = 1;
+ # IP:port of Clickhouse server
+ server = "localhost:18123";
+ allow_local = true;
+ retention {
+ # disabled by default
+ enable = true;
+ # drop | detach, please refer to ClickHouse docs for details
+ # http://clickhouse-docs.readthedocs.io/en/latest/query_language/queries.html#manipulations-with-partitions-and-parts
+ method = "drop";
+ # how many month the data should be kept in ClickHouse
+ period_months = 3;
+ # how often run the cleanup process
+ run_every = "7d";
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "${RSPAMD_TMPDIR}/rspamd.log"
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+}
+worker {
+ type = normal
+ bind_socket = ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_NORMAL}
+ count = 1
+ task_timeout = 60s;
+}
+worker {
+ type = controller
+ bind_socket = ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER}
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "${RSPAMD_TMPDIR}/stats.ucl"
+}
+lua = "${RSPAMD_TESTDIR}/lua/test_coverage.lua";
+modules {
+ path = "${RSPAMD_TESTDIR}/../../src/plugins/lua/"
+}
+lua = "${INSTALLROOT}/share/rspamd/rules/rspamd.lua"
diff --git a/test/functional/configs/composites.conf b/test/functional/configs/composites.conf
new file mode 100644
index 0000000..28b645e
--- /dev/null
+++ b/test/functional/configs/composites.conf
@@ -0,0 +1,87 @@
+options = {
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+}
+
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ task_timeout = 60s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+lua = {= env.LUA_SCRIPT =};
+
+composites {
+ EXPRESSIONS {
+ expression = "(EXPRESSIONS_A | ~EXPRESSIONS_B) & !EXPRESSIONS_C";
+ score = 5.0;
+ }
+
+ POLICY_REMOVE_WEIGHT {
+ expression = "POLICY_REMOVE_WEIGHT_A and ~POLICY_REMOVE_WEIGHT_B";
+ score = 5.0;
+ }
+ POLICY_FORCE_REMOVE {
+ expression = "POLICY_FORCE_REMOVE_A & ^POLICY_FORCE_REMOVE_B";
+ score = 5.0;
+ }
+ POLICY_FORCE_REMOVE_LEAVE {
+ expression = "-POLICY_FORCE_REMOVE_A and -POLICY_FORCE_REMOVE_B";
+ score = 5.0;
+ }
+ POLICY_LEAVE {
+ expression = "POLICY_LEAVE_A & -POLICY_LEAVE_B";
+ score = 5.0;
+ }
+
+ DEFAULT_POLICY_REMOVE_WEIGHT {
+ expression = "DEFAULT_POLICY_REMOVE_WEIGHT_A and DEFAULT_POLICY_REMOVE_WEIGHT_B";
+ score = 5.0;
+ policy = "remove_weight";
+ }
+ DEFAULT_POLICY_REMOVE_SYMBOL {
+ expression = "DEFAULT_POLICY_REMOVE_SYMBOL_A & DEFAULT_POLICY_REMOVE_SYMBOL_B";
+ score = 5.0;
+ policy = "remove_symbol";
+ }
+ DEFAULT_POLICY_LEAVE {
+ expression = "DEFAULT_POLICY_LEAVE_A & DEFAULT_POLICY_LEAVE_B";
+ score = 5.0;
+ policy = "leave";
+ }
+
+ SYMBOL_GROUPS {
+ expression = "!g+:positive & g-:negative & -g:any";
+ score = 5.0;
+ }
+
+ SYMOPTS1 {
+ expression = "OPTS[sym1]";
+ score = 5.0;
+ }
+
+ SYMOPTS2 {
+ expression = 'OPTS[/foo[0-9]/,sym2]';
+ score = 6.0;
+ }
+ SYMOPTS3 {
+ expression = 'OPTS[sym2,/FoO\//i]';
+ score = 6.0;
+ }
+ SYMOPTS4 {
+ expression = 'POSITIVE_A & OPTS[/>app.link$/i] & EXPRESSIONS';
+ score = 6.0;
+ }
+}
diff --git a/test/functional/configs/dkim-eddsa.key b/test/functional/configs/dkim-eddsa.key
new file mode 100644
index 0000000..45282e1
--- /dev/null
+++ b/test/functional/configs/dkim-eddsa.key
@@ -0,0 +1 @@
+m5kGxtckRfsNe5EuYTe7bvkDjSh7LXaX3aXyIMPGLR0=
diff --git a/test/functional/configs/dkim.conf b/test/functional/configs/dkim.conf
new file mode 100644
index 0000000..50712d1
--- /dev/null
+++ b/test/functional/configs/dkim.conf
@@ -0,0 +1,66 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+options = {
+ filters = ["dkim"]
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ dns {
+ retransmits = 10;
+ timeout = 2s;
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+}
+
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ keypair {
+ pubkey = "{= env.KEY_PUB1 =}";
+ privkey = "{= env.KEY_PVT1 =}";
+ }
+ task_timeout = 60s;
+}
+
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+
+dkim {
+
+sign_condition =<<EOD
+return function(task)
+ local dodkim = task:get_request_header('dodkim')
+ if not dodkim then return end
+ return {
+ key = "{= env.TESTDIR =}/configs/dkim.key",
+ domain = "cacophony.za.org",
+ selector = "dkim"
+ }
+end
+EOD;
+
+ dkim_cache_size = 2k;
+ dkim_cache_expire = 1d;
+ time_jitter = 6h;
+ trusted_only = false;
+ skip_multi = false;
+}
+modules {
+ path = "{= env.TESTDIR =}/../../src/plugins/lua/"
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
diff --git a/test/functional/configs/dkim.key b/test/functional/configs/dkim.key
new file mode 100644
index 0000000..3bc1fb8
--- /dev/null
+++ b/test/functional/configs/dkim.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANe3EETkiI1Exyrb
++VzbMSt90K8MXJA0GcyNs6MFCs9JPaTh90Zu2l7ki7m5LTUx6350AR/3hcvwjSHC
+ZjD6fvQ8/zfjN8kaLZ6DAaqtqSlpawIM+8glkuTEkIkpBED/OtDrba4Rd29iLFVu
+wQZXDtTjAAZKZPmtTZ5TXLrcCU6VAgMBAAECgYEA1BFvmBsIN8Gu/+6kNupya2xU
+NVM0yLu/xT5lpNV3LBO325oejAq8+d87kkl/LTW3a2jGFlQ0ICuLw+2mo24QUWRy
+v8if3oeBMlnLqHE+6wNjFVqo5sOjKzjO363xSXwXNUrBT7jDhnZcDN8w3/FecYKj
+ifGTVtUs1SLsYwhlc8ECQQDuCRymLZQ/imPn5eFVIydwUzg8ptZlvoA7bfIxUL9B
+QRX33s59kLCilA0tTed8Dd+GnxsT93XOj1ApIfBwmTSlAkEA5/63PDsN7fH+WInq
+VD8nU07M9S8LcGDlPbVVBr2S2I78/iwrSDAYtbkU2vEbhFK/JuKNML2j8OkzV3v1
+QulfMQJBALDzhx+l/HHr3+8RPhx7QKNIyiKUaAdEwbDsP8IXY8YPq1QThu9jM1v4
+sX7/TdkzuvoppwiFykbe1NlvCH279p0CQCmTg4Ee0DtBcCSr6rvYaZLLf329RZ6J
+LuwlMCy6ErQOxBZFEiiovfTrS2qFZToMnkc4uLbwdY36LQJTq7unGTECQCCok8Lz
+BeZtAw+TJofpOM3F2Rlm2qXiBVBeubhRedsiljG0hpvvLJBMppnQ6r27p5Jk39Sm
+aTRkxEKrxPWWLNM=
+-----END PRIVATE KEY----- \ No newline at end of file
diff --git a/test/functional/configs/dkim_signing/eddsa.conf b/test/functional/configs/dkim_signing/eddsa.conf
new file mode 100644
index 0000000..a8cdfaa
--- /dev/null
+++ b/test/functional/configs/dkim_signing/eddsa.conf
@@ -0,0 +1,8 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+dkim_signing {
+ path = "{= env.TESTDIR =}/configs/dkim-eddsa.key";
+ selector = "eddsa";
+ check_pubkey = true;
+ allow_pubkey_mismatch = false;
+}
diff --git a/test/functional/configs/dkim_signing/invalidate.conf b/test/functional/configs/dkim_signing/invalidate.conf
new file mode 100644
index 0000000..b7913cd
--- /dev/null
+++ b/test/functional/configs/dkim_signing/invalidate.conf
@@ -0,0 +1,8 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+dkim_signing {
+ path = "{= env.KEY_DIR =}/dkim-eddsa.key";
+ selector = "eddsa";
+ check_pubkey = true;
+ allow_pubkey_mismatch = false;
+}
diff --git a/test/functional/configs/dkim_signing/milter.conf b/test/functional/configs/dkim_signing/milter.conf
new file mode 100644
index 0000000..a373e16
--- /dev/null
+++ b/test/functional/configs/dkim_signing/milter.conf
@@ -0,0 +1,76 @@
+options = {
+ filters = ["dkim"]
+ url_tld = "{= env.URL_TLD =}"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ lua_path = "{= env.INSTALLROOT =}/share/rspamd/lib/?.lua"
+ dns {
+ nameserver = ["8.8.8.8", "8.8.4.4"];
+ retransmits = 10;
+ timeout = 2s;
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+}
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ task_timeout = 60s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+worker {
+ type = "rspamd_proxy";
+ count = 1;
+ timeout = 120;
+ upstream {
+ local {
+ hosts = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}";
+ default = true;
+ }
+ }
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_PROXY =}";
+ milter = true;
+}
+dkim_signing {
+ domain {
+ cacophony.za.org {
+ selectors = {
+ path: "{= env.TESTDIR =}/configs/dkim.key";
+ selector: "dkim";
+ }
+ selectors = {
+ path: "{= env.TESTDIR =}/configs/dkim-eddsa.key";
+ selector: "eddsa";
+ }
+ }
+ invalid.za.org {
+ selectors = [
+ { path: "{= env.TESTDIR =}/configs/dkim-eddsa.key";
+ selector: "eddsa"; }
+ ]
+ }
+ }
+ allow_pubkey_mismatch: true;
+}
+modules {
+ path = "{= env.TESTDIR =}/../../src/plugins/lua/dkim_signing.lua"
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+lua = "{= env.INSTALLROOT =}/share/rspamd/rules/rspamd.lua"
+lua = "{= env.TESTDIR =}/lua/params.lua"
diff --git a/test/functional/configs/dkim_signing/multiple.conf b/test/functional/configs/dkim_signing/multiple.conf
new file mode 100644
index 0000000..029c2b5
--- /dev/null
+++ b/test/functional/configs/dkim_signing/multiple.conf
@@ -0,0 +1,17 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+dkim_signing {
+ domain {
+ cacophony.za.org {
+ selectors = {
+ path: "{= env.TESTDIR =}/configs/dkim.key";
+ selector: "dkim";
+ }
+ selectors = {
+ path: "{= env.TESTDIR =}/configs/dkim-eddsa.key";
+ selector: "eddsa";
+ }
+ }
+ }
+ allow_pubkey_mismatch: false;
+}
diff --git a/test/functional/configs/dkim_signing/redis.conf b/test/functional/configs/dkim_signing/redis.conf
new file mode 100644
index 0000000..02dc2ea
--- /dev/null
+++ b/test/functional/configs/dkim_signing/redis.conf
@@ -0,0 +1,10 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+dkim_signing {
+ use_redis = true;
+ key_prefix = "TEST_DKIM_KEYS";
+ selector_prefix = "TEST_DKIM_SELECTORS";
+}
+redis {
+ servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}";
+}
diff --git a/test/functional/configs/dkim_signing/sign_maps.conf b/test/functional/configs/dkim_signing/sign_maps.conf
new file mode 100644
index 0000000..6993f1f
--- /dev/null
+++ b/test/functional/configs/dkim_signing/sign_maps.conf
@@ -0,0 +1,11 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+dkim_signing {
+ signing_table = [
+ "*@cacophony.za.org cacophony.za.org",
+ ];
+
+ key_table = [
+ "cacophony.za.org %:eddsa:m5kGxtckRfsNe5EuYTe7bvkDjSh7LXaX3aXyIMPGLR0=",
+ ];
+}
diff --git a/test/functional/configs/dkim_signing/simple.conf b/test/functional/configs/dkim_signing/simple.conf
new file mode 100644
index 0000000..9b812ec
--- /dev/null
+++ b/test/functional/configs/dkim_signing/simple.conf
@@ -0,0 +1,9 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+dkim_signing {
+ path = "{= env.TESTDIR =}/configs/dkim.key";
+ check_pubkey = true;
+ allow_pubkey_mismatch = false;
+ use_http_headers = true;
+ allow_headers_fallback = true;
+}
diff --git a/test/functional/configs/dynamic.conf b/test/functional/configs/dynamic.conf
new file mode 100644
index 0000000..b766644
--- /dev/null
+++ b/test/functional/configs/dynamic.conf
@@ -0,0 +1,117 @@
+[
+ {
+ "metric": "default",
+ "actions": [
+ {
+ "name": "reject",
+ "value": 20.0
+ },
+ {
+ "name": "add header",
+ "value": 6.0
+ }
+ ],
+ "symbols": [
+ {
+ "name": "SA_BODY_WORD",
+ "value": 10.0
+ },
+ {
+ "name": "FORGED_RECIPIENTS",
+ "value": 0.0
+ },
+ {
+ "name": "PHISHING",
+ "value": 0.0
+ },
+ {
+ "name": "PRECEDENCE_BULK",
+ "value": 2.0
+ },
+ {
+ "name": "SPAM_FLAG",
+ "value": 6.0
+ },
+ {
+ "name": "BAYES_SPAM",
+ "value": 10.0
+ },
+ {
+ "name": "BAYES_HAM",
+ "value": -6.0
+ },
+ {
+ "name": "MISSING_TO",
+ "value": 3.0
+ },
+ {
+ "name": "FUZZY_DENIED",
+ "value": 0.0
+ },
+ {
+ "name": "DMARC_POLICY_QUARANTINE",
+ "value": 3.500000
+ },
+ {
+ "name": "DMARC_POLICY_SOFTFAIL",
+ "value": 2.0
+ },
+ {
+ "name": "DNSWL_BLOCKED",
+ "value": 1.0
+ },
+ {
+ "name": "RCVD_COUNT_TWO",
+ "value": 1.0
+ },
+ {
+ "name": "R_SPF_FAIL",
+ "value": 10.0
+ },
+ {
+ "name": "R_DKIM_ALLOW",
+ "value": -1.500000
+ },
+ {
+ "name": "FAKE_REPLY",
+ "value": 2.0
+ },
+ {
+ "name": "SUBJECT_ENDS_EXCLAIM",
+ "value": 2.0
+ },
+ {
+ "name": "FORGED_SENDER_MAILLIST",
+ "value": 1.0
+ },
+ {
+ "name": "RCVD_NO_TLS_LAST",
+ "value": 1.0
+ },
+ {
+ "name": "HFILTER_URL_ONLY",
+ "value": 4.200000
+ },
+ {
+ "name": "URI_COUNT_ODD",
+ "value": 2.0
+ },
+ {
+ "name": "FORGED_RECIPIENTS_MAILLIST",
+ "value": 1.0
+ },
+ {
+ "name": "SEM_URIBL_FRESH15",
+ "value": 4.0
+ },
+ {
+ "name": "FROM_NEQ_ENVFROM",
+ "value": 1.0
+ },
+ {
+ "name": "DMARC_POLICY_REJECT",
+ "value": 3.0
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/test/functional/configs/empty.conf b/test/functional/configs/empty.conf
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/functional/configs/empty.conf
diff --git a/test/functional/configs/force_actions.conf b/test/functional/configs/force_actions.conf
new file mode 100644
index 0000000..aed3d05
--- /dev/null
+++ b/test/functional/configs/force_actions.conf
@@ -0,0 +1,88 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+force_actions {
+ rules {
+ FORCE_REJECT_TO_ADD_HEADER {
+ action = "add header";
+ expression = "UBER_REJECT";
+ require_action = ["reject"];
+ }
+ FORCE_REJECT_TO_NO_ACTION {
+ action = "no action";
+ expression = "UBER_REJECT2";
+ require_action = ["reject"];
+ }
+ FORCE_NO_ACTION_TO_REJECT {
+ action = "reject";
+ expression = "UBER_HAM";
+ require_action = ["no action"];
+ }
+ FORCE_NO_ACTION_TO_ADD_HEADER {
+ action = "add header";
+ expression = "UBER_HAM2";
+ require_action = ["no action"];
+ }
+ FORCE_ADD_HEADER_TO_NO_ACTION {
+ action = "no action";
+ expression = "UBER_ADD_HEADER";
+ require_action = ["add header"];
+ }
+ FORCE_ADD_HEADER_TO_REJECT {
+ action = "reject";
+ expression = "UBER_ADD_HEADER2";
+ require_action = ["add header"];
+ }
+ }
+}
+
+
+settings {
+ id_reject {
+ id = "id_reject";
+ apply {
+ symbols {
+ UBER_REJECT = 100500.0;
+ }
+ }
+ }
+ id_reject_no_action {
+ id = "id_reject_no_action";
+ apply {
+ symbols {
+ UBER_REJECT2 = 100500.0;
+ }
+ }
+ }
+ id_no_action {
+ id = "id_no_action";
+ apply {
+ symbols {
+ UBER_HAM = 1.0;
+ }
+ }
+ }
+ id_no_action_to_add_header {
+ id = "id_no_action_to_add_header";
+ apply {
+ symbols {
+ UBER_HAM2 = 1.0;
+ }
+ }
+ }
+ id_add_header {
+ id = "id_add_header";
+ apply {
+ symbols {
+ UBER_ADD_HEADER = 50500.0;
+ }
+ }
+ }
+ id_add_header_to_reject {
+ id = "id_add_header_to_reject";
+ apply {
+ symbols {
+ UBER_ADD_HEADER2 = 50500.0;
+ }
+ }
+ }
+}
diff --git a/test/functional/configs/fuzzy-encryption-key.conf b/test/functional/configs/fuzzy-encryption-key.conf
new file mode 100644
index 0000000..522081b
--- /dev/null
+++ b/test/functional/configs/fuzzy-encryption-key.conf
@@ -0,0 +1,2 @@
+# Setting this to null does not work out so it's hidden in an include
+encryption_key = {= env.FUZZY_ENCRYPTION_KEY =};
diff --git a/test/functional/configs/fuzzy.conf b/test/functional/configs/fuzzy.conf
new file mode 100644
index 0000000..8af1cfa
--- /dev/null
+++ b/test/functional/configs/fuzzy.conf
@@ -0,0 +1,95 @@
+redis {
+ servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}";
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+options = {
+ filters = "fuzzy_check";
+ pidfile = "{= env.TMPDIR =}/rspamd.pid";
+ control_socket = "{= env.TMPDIR =}/rspamd.sock mode=0600";
+ url_tld = "{= env.TESTDIR =}/../lua/unit/test_tld.dat";
+ dns {
+ retransmits = 10;
+ timeout = 2s;
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+ symbol {
+ weight = 10.0;
+ name = "{= env.FLAG1_SYMBOL =}";
+ }
+ symbol {
+ weight = -1.0;
+ name = "{= env.FLAG2_SYMBOL =}";
+ }
+}
+
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}";
+ count = 1
+ task_timeout = 60s;
+}
+
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}";
+ count = 1
+ secure_ip = ["{= env.LOCAL_ADDR =}"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl";
+}
+
+worker {
+ count = 1;
+ backend = "{= env.FUZZY_BACKEND =}";
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_FUZZY =}";
+ type = "fuzzy";
+ hashfile = "{= env.TMPDIR =}/fuzzy.db";
+ allow_update = ["{= env.LOCAL_ADDR =}"];
+ encrypted_only = {= env.FUZZY_ENCRYPTED_ONLY =};
+ keypair {
+ privkey = "{= env.KEY_PVT1 =}";
+ pubkey = "{= env.KEY_PUB1 =}";
+ }
+}
+
+fuzzy_check {
+ min_bytes = 100;
+ timeout = 1s;
+ retransmits = 10;
+
+ rule {
+ min_bytes = 0;
+ min_length = 0;
+ algorithm = "{= env.FUZZY_ALGORITHM =}";
+ servers = "{= env.LOCAL_ADDR =}:{= env.PORT_FUZZY =}";
+ symbol = "R_TEST_FUZZY";
+ max_score = 10.0;
+ mime_types = ["application/*"];
+ read_only = false;
+ skip_unknown = true;
+ skip_hashes = "{= env.TMPDIR =}/skip_hash.map";
+ fuzzy_key = {= env.FUZZY_KEY =};
+ fuzzy_shingles_key = {= env.FUZZY_SHINGLES_KEY =};
+.include "{= env.FUZZY_INCLUDE =}";
+ fuzzy_map = {
+ R_TEST_FUZZY_DENIED {
+ max_score = 10.0;
+ flag = {= env.FLAG1_NUMBER =};
+ }
+ R_TEST_FUZZY_WHITE {
+ max_score = 1.0;
+ flag = {= env.FLAG2_NUMBER =};
+ }
+ }
+ }
+}
diff --git a/test/functional/configs/known_senders-local.conf b/test/functional/configs/known_senders-local.conf
new file mode 100644
index 0000000..40522ae
--- /dev/null
+++ b/test/functional/configs/known_senders-local.conf
@@ -0,0 +1,4 @@
+known_senders {
+ enabled = true;
+ domains = "{= env.TESTDIR =}/configs/maps/known_senders_domains.map";
+}
diff --git a/test/functional/configs/known_senders.conf b/test/functional/configs/known_senders.conf
new file mode 100644
index 0000000..0880cea
--- /dev/null
+++ b/test/functional/configs/known_senders.conf
@@ -0,0 +1,7 @@
+.include "{= env.TESTDIR =}/../../conf/rspamd.conf"
+
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua"
+
+.include(priority=1,duplicate=merge) "{= env.TESTDIR =}/configs/known_senders-local.conf"
+.include(priority=1,duplicate=merge) "{= env.TESTDIR =}/configs/merged-local.conf"
+.include(priority=2,duplicate=replace) "{= env.TESTDIR =}/configs/merged-override.conf"
diff --git a/test/functional/configs/loggingtest-local.conf b/test/functional/configs/loggingtest-local.conf
new file mode 100644
index 0000000..7330d97
--- /dev/null
+++ b/test/functional/configs/loggingtest-local.conf
@@ -0,0 +1,5 @@
+logging {
+ type = "{= env.LOGGINGTYPE =}";
+ json = {= env.JSON =};
+ systemd = {= env.SYSTEMD =};
+}
diff --git a/test/functional/configs/loggingtest.conf b/test/functional/configs/loggingtest.conf
new file mode 100644
index 0000000..99026df
--- /dev/null
+++ b/test/functional/configs/loggingtest.conf
@@ -0,0 +1,3 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/trivial.conf"
+
+.include(priority=1,duplicate=merge) "{= env.TESTDIR =}/configs/loggingtest-local.conf"
diff --git a/test/functional/configs/lua_script.conf b/test/functional/configs/lua_script.conf
new file mode 100644
index 0000000..8798bff
--- /dev/null
+++ b/test/functional/configs/lua_script.conf
@@ -0,0 +1,25 @@
+options = {
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+}
+
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ task_timeout = 60s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+lua = "{= env.LUA_SCRIPT =}";
diff --git a/test/functional/configs/lua_test.conf b/test/functional/configs/lua_test.conf
new file mode 100644
index 0000000..1d36536
--- /dev/null
+++ b/test/functional/configs/lua_test.conf
@@ -0,0 +1,52 @@
+options = {
+ filters = ["spf", "dkim", "regexp"]
+ url_tld = "{= env.URL_TLD =}"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ map_watch_interval = {= env.MAP_WATCH_INTERVAL =};
+ dns {
+ retransmits = 10;
+ timeout = 2s;
+ fake_records = [{
+ name = "example.com",
+ type = "a";
+ replies = ["93.184.216.34"];
+ }, {
+ name = "site.resolveme",
+ type = "a";
+ replies = ["127.0.0.1"];
+ }, {
+ name = "not-resolvable.com",
+ type = "a";
+ rcode = 'norec';
+ }]
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+ log_usec = true;
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+}
+
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ task_timeout = 10s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+lua = "{= env.LUA_SCRIPT =}";
diff --git a/test/functional/configs/maps/domains.cdb b/test/functional/configs/maps/domains.cdb
new file mode 100644
index 0000000..889268e
--- /dev/null
+++ b/test/functional/configs/maps/domains.cdb
Binary files differ
diff --git a/test/functional/configs/maps/domains.list b/test/functional/configs/maps/domains.list
new file mode 100644
index 0000000..04b0a9b
--- /dev/null
+++ b/test/functional/configs/maps/domains.list
@@ -0,0 +1,5 @@
+example.com
+cacophony.za.org both:1.0
+highsecure.ru bl:1.0
+rspamd.com wl:2.0
+#other.com \ No newline at end of file
diff --git a/test/functional/configs/maps/domains.list.2 b/test/functional/configs/maps/domains.list.2
new file mode 100644
index 0000000..15fb908
--- /dev/null
+++ b/test/functional/configs/maps/domains.list.2
@@ -0,0 +1,16 @@
+rspamd-test.com
+test.com
+test2.com
+test3.com
+test4.com
+test5.com
+test6.com
+test7.com
+test8.com
+test9.com
+test10.com
+test11.com
+test12.com
+test13.com
+test14.com
+#other.com
diff --git a/test/functional/configs/maps/dynamic_symbols.map b/test/functional/configs/maps/dynamic_symbols.map
new file mode 100644
index 0000000..ec92c74
--- /dev/null
+++ b/test/functional/configs/maps/dynamic_symbols.map
@@ -0,0 +1,2 @@
+foo DYN_TEST1:10:opt1,opt2
+bar DYN_TEST2:20:opt3,opt4
diff --git a/test/functional/configs/maps/external_relay.hostname_map b/test/functional/configs/maps/external_relay.hostname_map
new file mode 100644
index 0000000..fdb4fc0
--- /dev/null
+++ b/test/functional/configs/maps/external_relay.hostname_map
@@ -0,0 +1,3 @@
+cool.example.org direct
+lame.example.net
+
diff --git a/test/functional/configs/maps/external_relay.ip_map b/test/functional/configs/maps/external_relay.ip_map
new file mode 100644
index 0000000..f5b106f
--- /dev/null
+++ b/test/functional/configs/maps/external_relay.ip_map
@@ -0,0 +1,2 @@
+2001:db8::/32
+198.51.100.0/24
diff --git a/test/functional/configs/maps/external_relay.user_map b/test/functional/configs/maps/external_relay.user_map
new file mode 100644
index 0000000..bd04568
--- /dev/null
+++ b/test/functional/configs/maps/external_relay.user_map
@@ -0,0 +1,2 @@
+user@example.net
+
diff --git a/test/functional/configs/maps/external_relay_ip.list b/test/functional/configs/maps/external_relay_ip.list
new file mode 100644
index 0000000..3fc5c17
--- /dev/null
+++ b/test/functional/configs/maps/external_relay_ip.list
@@ -0,0 +1 @@
+192.168.1.1 \ No newline at end of file
diff --git a/test/functional/configs/maps/ip.list b/test/functional/configs/maps/ip.list
new file mode 100644
index 0000000..f35c9bc
--- /dev/null
+++ b/test/functional/configs/maps/ip.list
@@ -0,0 +1,4 @@
+127.0.0.1
+#127.0.0.2
+10.0.0.0/8
+[::1]/128 \ No newline at end of file
diff --git a/test/functional/configs/maps/ip2.list b/test/functional/configs/maps/ip2.list
new file mode 100644
index 0000000..7d99d28
--- /dev/null
+++ b/test/functional/configs/maps/ip2.list
@@ -0,0 +1,3 @@
+8.8.8.8 test one
+::1 another
+192.168.1.1
diff --git a/test/functional/configs/maps/known_senders_domains.map b/test/functional/configs/maps/known_senders_domains.map
new file mode 100644
index 0000000..8ddda0f
--- /dev/null
+++ b/test/functional/configs/maps/known_senders_domains.map
@@ -0,0 +1,2 @@
+outlook.com
+example.com
diff --git a/test/functional/configs/maps/map.list b/test/functional/configs/maps/map.list
new file mode 100644
index 0000000..8e68bab
--- /dev/null
+++ b/test/functional/configs/maps/map.list
@@ -0,0 +1,3 @@
+foo bar
+asdf.example.com value
+asdf
diff --git a/test/functional/configs/maps/mid.list b/test/functional/configs/maps/mid.list
new file mode 100644
index 0000000..b89c084
--- /dev/null
+++ b/test/functional/configs/maps/mid.list
@@ -0,0 +1,2 @@
+cacophony.za.org /^<[A-z0-9+]{18}>$/
+mom.za.org
diff --git a/test/functional/configs/maps/mime_types.wl b/test/functional/configs/maps/mime_types.wl
new file mode 100644
index 0000000..eca07bd
--- /dev/null
+++ b/test/functional/configs/maps/mime_types.wl
@@ -0,0 +1 @@
+/^hello_world\.exe$/
diff --git a/test/functional/configs/maps/multiple.list b/test/functional/configs/maps/multiple.list
new file mode 100644
index 0000000..3d4f32f
--- /dev/null
+++ b/test/functional/configs/maps/multiple.list
@@ -0,0 +1,12 @@
+#empty string
+user1@example.com
+#just score
+user2@example.com 10
+#just symbol
+user3@example.com SYM1
+#unknown symbol
+user4@example.com SYM2
+#symbol + score
+user5@example.com SYM1:-10.1
+#symbol + score + options
+user6@example.com SYM1:-10.1:opt1,opt2
diff --git a/test/functional/configs/maps/rcvd.list b/test/functional/configs/maps/rcvd.list
new file mode 100644
index 0000000..5c59711
--- /dev/null
+++ b/test/functional/configs/maps/rcvd.list
@@ -0,0 +1 @@
+2a01:7c8:aab6:26d:5054:ff:fed1:1da2
diff --git a/test/functional/configs/maps/rcvd2.list b/test/functional/configs/maps/rcvd2.list
new file mode 100644
index 0000000..97dba5b
--- /dev/null
+++ b/test/functional/configs/maps/rcvd2.list
@@ -0,0 +1,2 @@
+151.18.193.131
+
diff --git a/test/functional/configs/maps/redir.map b/test/functional/configs/maps/redir.map
new file mode 100644
index 0000000..5b7eb38
--- /dev/null
+++ b/test/functional/configs/maps/redir.map
@@ -0,0 +1,3 @@
+t.co
+bit.ly
+127.0.0.1
diff --git a/test/functional/configs/maps/regexp.list b/test/functional/configs/maps/regexp.list
new file mode 100644
index 0000000..ceb2bf5
--- /dev/null
+++ b/test/functional/configs/maps/regexp.list
@@ -0,0 +1,5 @@
+/^.*@example.com/i
+/^user.*@.*com/i
+/foo/ bar
+/asdf\.example\.com/ value
+/^asdf$/
diff --git a/test/functional/configs/maps/strict.phishing b/test/functional/configs/maps/strict.phishing
new file mode 100644
index 0000000..af2de57
--- /dev/null
+++ b/test/functional/configs/maps/strict.phishing
@@ -0,0 +1 @@
+myspace.com
diff --git a/test/functional/configs/maps/stricter.phishing b/test/functional/configs/maps/stricter.phishing
new file mode 100644
index 0000000..a1240ea
--- /dev/null
+++ b/test/functional/configs/maps/stricter.phishing
@@ -0,0 +1 @@
+bank.com
diff --git a/test/functional/configs/maps/top.list b/test/functional/configs/maps/top.list
new file mode 100644
index 0000000..d8a152e
--- /dev/null
+++ b/test/functional/configs/maps/top.list
@@ -0,0 +1,2 @@
+au
+#bg \ No newline at end of file
diff --git a/test/functional/configs/maps/url_compose_map.list b/test/functional/configs/maps/url_compose_map.list
new file mode 100644
index 0000000..808c455
--- /dev/null
+++ b/test/functional/configs/maps/url_compose_map.list
@@ -0,0 +1,3 @@
+*.dirty.sanchez.com
+!not.dirty.sanchez.com
+41.black.sanchez.com \ No newline at end of file
diff --git a/test/functional/configs/maps/url_compose_map_for_mails.list b/test/functional/configs/maps/url_compose_map_for_mails.list
new file mode 100644
index 0000000..1d54a3e
--- /dev/null
+++ b/test/functional/configs/maps/url_compose_map_for_mails.list
@@ -0,0 +1,3 @@
+*.dirty.sanchez.com
+!admin.dirty.sanchez.com
+41.black.sanchez.com \ No newline at end of file
diff --git a/test/functional/configs/maps/users.list b/test/functional/configs/maps/users.list
new file mode 100644
index 0000000..696fb6b
--- /dev/null
+++ b/test/functional/configs/maps/users.list
@@ -0,0 +1 @@
+bob
diff --git a/test/functional/configs/maps/utf.list b/test/functional/configs/maps/utf.list
new file mode 100644
index 0000000..4709308
--- /dev/null
+++ b/test/functional/configs/maps/utf.list
@@ -0,0 +1 @@
+/васисуал/iu
diff --git a/test/functional/configs/merged-local.conf b/test/functional/configs/merged-local.conf
new file mode 100644
index 0000000..0708e3c
--- /dev/null
+++ b/test/functional/configs/merged-local.conf
@@ -0,0 +1,972 @@
+history_redis {
+ enabled = false;
+}
+
+neural {
+ enabled = false;
+}
+
+bayes_expiry {
+ enabled = false;
+}
+
+metric_exporter {
+ enabled = false;
+}
+
+emails {
+ "whitelist" = [
+ "rspamd-test.com"
+ ]
+ rules {
+ "RSPAMD_EMAILBL_FULL" {
+ dnsbl = "test5.uribl";
+ replyto = true;
+ }
+ "RSPAMD_EMAILBL_DOMAINONLY" {
+ dnsbl = "test6.uribl";
+ domain_only = true;
+ replyto = true;
+ }
+ }
+}
+
+external_relay {
+ enabled = {= env.EXTERNAL_RELAY_ENABLED =};
+
+ rules {
+ EXTERNAL_RELAY_AUTHENTICATED {
+ strategy = "authenticated";
+ user_map = "{= env.TESTDIR =}/configs/maps/external_relay.user_map";
+ }
+ EXTERNAL_RELAY_COUNT {
+ count = 4;
+ # `count` strategy always pops Received headers out, this will break other rules.
+ # So it should always be the last rule.
+ priority = 30;
+ strategy = "count";
+ }
+ EXTERNAL_RELAY_HOSTNAME_MAP {
+ hostname_map = "{= env.TESTDIR =}/configs/maps/external_relay.hostname_map";
+ strategy = "hostname_map";
+ }
+ EXTERNAL_RELAY_IP_MAP {
+ ip_map = "{= env.TESTDIR =}/configs/maps/external_relay.ip_map";
+ strategy = "ip_map";
+ }
+ EXTERNAL_RELAY_LOCAL {
+ strategy = "local";
+ }
+ }
+}
+
+greylist {
+ check_local = true;
+ timeout = 4;
+}
+
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+ log_usec = true;
+}
+
+mid = {
+ source = {
+ url = [
+ "https://maps.rspamd.com/rspamd/mid.inc.zst",
+ "fallback+file://{= env.TESTDIR =}/../../../conf/mid.inc",
+ "file://{= env.TESTDIR =}/configs/maps/mid.list"
+ ];
+ }
+}
+
+mime_types {
+ file = [
+ "https://maps.rspamd.com/rspamd/mime_types.inc.zst",
+ "fallback+file://{= env.TESTDIR =}/../../../conf/mime_types.inc"
+ ];
+ extension_map {
+ html = "text/html";
+ txt [
+ "message/disposition-notification",
+ "text/plain",
+ "text/rfc822-headers",
+ ]
+ pdf [
+ "application/octet-stream",
+ "application/pdf",
+ ]
+ }
+ filename_whitelist = "{= env.TESTDIR =}/configs/maps/mime_types.wl";
+}
+
+options = {
+ pidfile = "{= env.TMPDIR =}/rspamd.pid";
+ url_tld = "{= env.TESTDIR =}/../lua/unit/test_tld.dat";
+ dns {
+ nameserver = ["8.8.8.8", "8.8.4.4"];
+ retransmits = 10;
+ timeout = 2s;
+ fake_records = [{
+ # non-existent records requested by 350_surbl tests
+ name = "114.73.21.104.test4.uribl", type = "a", rcode = "norec"},
+ {name = "153.23.128.52.test4.uribl", type = "a", rcode = "norec"},
+ {name = "158.136.181.135.test4.uribl", type = "a", rcode = "norec"},
+ {name = "177.115.236.44.test4.uribl", type = "a", rcode = "norec"},
+ {name = "180.136.102.34.test4.uribl", type = "a", rcode = "norec"},
+ {name = "180.144.67.172.test4.uribl", type = "a", rcode = "norec"},
+ {name = "2.7.9.4.5.1.8.6.0.0.0.0.0.0.0.0.0.0.0.0.7.3.0.3.0.0.7.4.6.0.6.2.test4.uribl", type = "a", rcode = "norec"},
+ {name = "217.228.62.64.test4.uribl", type = "a", rcode = "norec"},
+ {name = "34.216.184.93.test4.uribl", type = "a", rcode = "norec"},
+ {name = "4.b.0.9.3.4.c.a.0.0.0.0.0.0.0.0.0.0.0.0.1.3.0.3.0.0.7.4.6.0.6.2.test4.uribl", type = "a", rcode = "norec"},
+ {name = "4eikheqjb4rb3y4oxgnfxek9wrwnyii4.test.uribl", type = "a", rcode = "norec"},
+ {name = "6.4.9.1.8.c.5.2.3.9.8.1.8.4.2.0.1.0.0.0.0.2.2.0.0.0.8.2.6.0.6.2.test4.uribl", type = "a", rcode = "norec"},
+ {name = "69so7b146n15x6qkr8rj9x8iqb7zfr1s.test.uribl", type = "a", rcode = "norec"},
+ {name = "6cqpxfrojdnzawwjmacjwtstzwehxnzb.test.uribl", type = "a", rcode = "norec"},
+ {name = "7.5.2.e.9.5.e.f.f.f.1.9.c.3.0.f.0.0.0.0.0.0.0.0.1.0.c.3.0.0.6.2.test4.uribl", type = "a", rcode = "norec"},
+ {name = "baddomain.com.test2.uribl", type = "a", rcode = "norec"},
+ {name = "baddomain.com.test3.uribl", type = "a", rcode = "norec"},
+ {name = "bbjo9td11ewijyjkq8rsn4j3kxhthz4m.test.uribl", type = "a", rcode = "norec"},
+ {name = "emailbl.com.test2.uribl", type = "a", rcode = "norec"},
+ {name = "emailbl.com.test3.uribl", type = "a", rcode = "norec"},
+ {name = "emailbl.com.test6.uribl", type = "a", rcode = "norec"},
+ {name = "example.com.test3.uribl", type = "a", rcode = "norec"},
+ {name = "example.com.test6.uribl", type = "a", rcode = "norec"},
+ {name = "example.com.test7.uribl", type = "a", rcode = "norec"},
+ {name = "example.net.test3.uribl", type = "a", rcode = "norec"},
+ {name = "example.net.test7.uribl", type = "a", rcode = "norec"},
+ {name = "example.org.test2.uribl", type = "a", rcode = "norec"},
+ {name = "example.org.test3.uribl", type = "a", rcode = "norec"},
+ {name = "example.org.test7.uribl", type = "a", rcode = "norec"},
+ {name = "example.ru.test2.uribl", type = "a", rcode = "norec"},
+ {name = "example.ru.test7.uribl", type = "a", rcode = "norec"},
+ {name = "gdhhir83i5pjk6s8i3e5afwa4md7uns7.test.uribl", type = "a", rcode = "norec"},
+ {name = "k8qo8m33z19cqejfncirs85rf4nr9h3u.test.uribl", type = "a", rcode = "norec"},
+ {name = "kr1adm7tnzuudiftdt1g4t6yg1rbt1ez.test.uribl", type = "a", rcode = "norec"},
+ {name = "rspamd.com.test2.uribl", type = "a", rcode = "norec"},
+ {name = "rspamd.com.test3.uribl", type = "a", rcode = "norec"},
+ {name = "rspamd.com.test7.uribl", type = "a", rcode = "norec"},
+ {name = "rspamd.tk.test3.uribl", type = "a", rcode = "norec"},
+ {name = "rspamd.tk.test7.uribl", type = "a", rcode = "norec"},
+ {name = "sanchez.com.test2.uribl", type = "a", rcode = "norec"},
+ {name = "sanchez.com.test3.uribl", type = "a", rcode = "norec"},
+ {name = "sanchez.com.test7.uribl", type = "a", rcode = "norec"},
+ {name = "subdomain.emailbl.com.test6.uribl", type = "a", rcode = "norec"},
+ {name = "testtest.com.test2.uribl", type = "a", rcode = "norec"},
+ {name = "testtest.com.test3.uribl", type = "a", rcode = "norec"},
+ {name = "testtest.com.test7.uribl", type = "a", rcode = "norec"},
+ {name = "user.baddomain.com.test5.uribl", type = "a", rcode = "norec"},
+ {name = "user.example.com.test5.uribl", type = "a", rcode = "norec"},
+ {name = "xn--80arbjktj.xn--p1ai.test3.uribl", type = "a", rcode = "norec"},
+ {name = "xn--80arbjktj.xn--p1ai.test7.uribl", type = "a", rcode = "norec"},
+ {name = "y84tis6xzaf41h4p5kzxiw6puixnm43k.test.uribl", type = "a", rcode = "norec"},
+ # other stuff is here too! :\
+ { # ed25519
+ name = "test._domainkey.example.com";
+ type = txt;
+ replies = ["k=ed25519; p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y="];
+ },
+ {
+ name = "brisbane._domainkey.football.example.com";
+ type = txt;
+ replies = ["v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo="];
+ },
+ {
+ name = "test._domainkey.football.example.com";
+ type = txt;
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkHlOQoBTzWRiGs5V6NpP3idY6Wk08a5qhdR6wy5bdOKb2jLQiY/J16JYi0Qvx/byYzCNb3W91y3FutACDfzwQ/BC/e/8uBsCR+yz1Lxj+PL6lHvqMKrM3rG4hstT5QjvHO9PzoxZyVYLzBfO2EeC3Ip3G+2kryOTIKT+l/K4w3QIDAQAB"],
+ },
+ {
+ name = "dkim._domainkey.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXtxBE5IiNRMcq2/lc2zErfdCvDFyQNBnMjbOjBQrPST2k4fdGbtpe5Iu5uS01Met+dAEf94XL8I0hwmYw+n70PP834zfJGi2egwGqrakpaWsCDPvIJZLkxJCJKQRA/zrQ622uEXdvYixVbsEGVw7U4wAGSmT5rU2eU1y63AlOlQIDAQAB"];
+ },
+ {
+ name = "eddsa._domainkey.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=ed25519; p=+nU+aC33ICeS4zx8VUjFYCtxj0fRbHWQn2gP2hTkm9w="];
+ },
+ {
+ name = "dkim._domainkey.invalid.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEEXmNGQq7PUrr9Mg4UakTFHgXBCy2DOztkrZm+0OrVWtiRzGluxBkbOWTBwuU3/Yw97yTphBMQxzWFN603/f/KPAQcF/Lc1l+6kmIBBxNXjjGuOK/3PYKZVntUdKmqcQBYfnHdzH2Tohbuyx1a7xqnv6VSChqQrZU4CwkeT3+eQIDAQAB"];
+ },
+ {
+ name = "eddsa._domainkey.invalid.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=ed25519; p=Wkkrp5DJTvknDMGWYv8vm3p3sZjiQp03LZo80RregY8="];
+ },
+ {
+ name = "dkim._domainkey.rspamd.com",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCd/XhZBEGGAss48lEuMmwZv9lOFf6FTllBiQ3sPhdTpDdIPaW9TInW7iYnYD/bXHeVxYAyD/sKhYk6+qGBRu10rEi+iyPvLCIED+Boq0tEQosuKuV6Fjoomb+QhZY9KdjyZTjsrFPZ+wCkUY/30uTmpX2SwSqyxxlK0pUIsRgMAQIDAQAB"];
+ },
+ {
+ name = "_dmarc.rspamd.com",
+ type = "txt";
+ rcode = 'norec';
+ },
+ {
+ name = "dkim._domainkey.highsecure.ru",
+ type = "txt";
+ replies = ["p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK4ZQYky30GH0Ak9OQ1fv3IdFNbpOtpa4S/PR20ZLgPXfd/FCA//ztUmu7kHlELI+/+4f8W+xX0oZlOc/cFxhopRjXZMlSsQqmWOZ40/GxWFBtcqafKu78FCqO7URqZUmMCM5Jlp4zt/yzH3dbYNG3i5PVlB5QtQnZvY+dvBL3dwIDAQAB"];
+ },
+ {
+ name = "_dmarc.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=none; sp=reject"];
+ },
+ {
+ name = "_dmarc.my.mom.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject"];
+ },
+ {
+ name = "example.net",
+ type = "txt";
+ replies = ["v=spf1 -all"];
+ },
+ {
+ name = "fail4.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 redirect=asdfsfewewrredfs"];
+ },
+ {
+ name = "_dmarc.reject.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject"];
+ },
+ {
+ name = "spf.cacophony.za.org",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.4.4 -all"];
+ },
+ {
+ name = "fail7.org.org.za",
+ type = "a";
+ rcode = 'norec';
+ },
+ {
+ name = "fail6.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 mx -all"];
+ },
+ {
+ name = "fail6.org.org.za",
+ type = "mx";
+ rcode = 'norec';
+ },
+ {
+ name = "fail7.org.org.za",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "_dmarc.quarantine.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=quarantine"];
+ },
+ {
+ name = "_dmarc.yo.mom.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject; aspf=s; adkim=s;"];
+ },
+ {
+ name = "yo.mom.za.org",
+ type = "txt";
+ replies = ["v=spf1 ip4:37.48.67.26 -all"];
+ },
+ {
+ name = "testdkim._domainkey.mom.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3v4VPE1QMHUzsMRbC8VzXNq82mDjiv9Gi1NB/YYC+vIYZT+sE/Uxnr0Clk8C2jgzEr3jcxgQEWZfMtEEg/EfEJvh4SrXWv9c0gw1EEfxKxX9i+r8yBQtc/EWospWVDkhF2lAvQAK1lV1ZiU7psJ6fh1CI39uZyWdAktZzWLf0zQIDAQAB"];
+ },
+ {
+ name = "_dmarc.rspamd.tk",
+ type = "txt";
+ replies = ["bio=a263adeab8acdcdb8b89e127b67d696061fdfbee"];
+ },
+ {
+ name = "fail2.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.4.4 include:www.dnssec-failed.org -all"];
+ },
+ {
+ name = "fail3.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 include:total.barf -all"];
+ },
+ {
+ name = "mom.za.org",
+ type = "txt";
+ replies = ["v=spf1 ip4:37.48.67.26 -all"];
+ },
+ {
+ name = "testdkim._domainkey.asdf.rspamd.tk", # testdkim._domainkey.asdf.rspamd.tk is an alias for rspamd.tk
+ type = "txt";
+ replies = ["bio=a263adeab8acdcdb8b89e127b67d696061fdfbee"];
+ },
+ {
+ name = "testdkim._domainkey.rspamd.tk", # testdkim._domainkey.rspamd.tk is an alias for rspamd.tk
+ type = "txt";
+ replies = ["bio=a263adeab8acdcdb8b89e127b67d696061fdfbee"];
+ },
+ {
+ name = "pass1.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 include:pass2.org.org.za -all"];
+ },
+ {
+ name = "95.142.99.88.in-addr.arpa",
+ type = "ptr";
+ replies = ["mail.highsecure.ru"];
+ },
+ {
+ name = "mail.highsecure.ru",
+ type = "a";
+ replies = ["88.99.142.95"];
+ },
+ {
+ name = "mail.highsecure.ru",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "1.0.66.128.in-addr.arpa",
+ type = "ptr";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "182.216.85.209.in-addr.arpa",
+ type = "ptr";
+ replies = ["mail-qt0-f182.google.com"];
+ },
+ {
+ name = "crazyspf.cacophony.za.org",
+ type = "txt";
+ replies = ["v=spf1 ptr:cacophony.za.org ptr:rspamd.com ptr:yahoo.com ptr:yahoo.net ptr:highsecure.ru -all"];
+ },
+ {
+ name = "pass2.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 -all"];
+ },
+ {
+ name = "_dmarc.yoni.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject; sp=none;"];
+ },
+ {
+ name = "fail10.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 redirect=fail5.org.org.za"];
+ },
+ {
+ name = "fail11.org.org.za",
+ type = "txt";
+ replies = ["v=sPF1 ip4:8.8.8.8 -all"];
+ },
+ {
+ name = "fail5.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 OMGBARF"];
+ },
+ {
+ name = "fail7.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 a -all"];
+ },
+ {
+ name = "trusted.com",
+ type = "txt";
+ replies = ["v=spf1 ip4:192.168.1.1"];
+ },
+ {
+ name = "external.com",
+ type = "txt";
+ replies = ["v=spf1 ip4:37.48.67.26"];
+ },
+ {
+ name = "co.za",
+ type = "txt";
+ rcode = 'norec';
+ },
+ {
+ name = "testdkim1._domainkey.yoni.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=BARF"];
+ },
+ {
+ name = "_dmarc.yoni.za.net",
+ type = "txt";
+ replies = ["v=DMARC1; p=none; sp=quarantine"];
+ },
+ {
+ name = "za",
+ type = "txt";
+ replies = ["Top-level domain for South Africa"];
+ },
+ {
+ name = "_dmarc.foo.yoni.za.org",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.foo.cacophony.za.org",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.foo.yoni.za.net",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.dnssec-failed.org",
+ type = "txt";
+ rcode = 'timeout';
+ },
+ {
+ name = "_dmarc.example.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.zero_pct.com",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject; sp=quarantine; pct=0"];
+ },
+ {
+ name = "example.com",
+ type = "txt";
+ replies = ["$Id: example.com 4415 2015-08-24 20:12:23Z davids $", "v=spf1 -all"];
+ },
+ {
+ name = "example.com",
+ type = "a";
+ replies = ["93.184.216.34"];
+ },
+ {
+ name = "testdkim1._domainkey.dnssec-failed.org",
+ type = "txt";
+ rcode = 'timeout';
+ },
+ {
+ name = "total.barf",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.foo.cacophony.za.org",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "zzzzaaaa",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "asdfsfewewrredfs",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "95.142.99.88.asn.rspamd.com",
+ type = "txt";
+ replies = ["24940|88.99.0.0/16|DE|ripencc|"];
+ },
+ {
+ name = "2.a.d.1.1.d.e.f.f.f.0.0.4.5.0.5.d.6.2.0.6.b.a.a.8.c.7.0.1.0.a.2.asn6.rspamd.com",
+ type = "txt";
+ replies = ["20857|2a01:7c8::/32|NL|ripencc|"];
+ },
+ {
+ name = "2.a.d.1.1.d.e.f.f.f.0.0.4.5.0.5.d.6.2.0.6.b.a.a.8.c.7.0.1.0.a.2.rspamd.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "2.a.d.1.1.d.e.f.f.f.0.0.4.5.0.5.d.6.2.0.6.b.a.a.8.c.7.0.1.0.a.2.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "rspamd.com",
+ type = "txt";
+ replies = ["v=spf1 mx -all"];
+ },
+ {
+ name = "rspamd.com",
+ type = "mx";
+ replies = ["10 mail.highsecure.ru"];
+ },
+ {
+ name = "95.142.99.88.rspamd.com",
+ type = "a";
+ rcode = 'norec';
+ },
+ {
+ name = "95.142.99.88.rspamd.com",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "2.0.0.127.rspamd.com",
+ type = "a";
+ replies = ["127.0.0.1"];
+ },
+ {
+ name = "8.8.8.8.asn.rspamd.com",
+ type = "txt";
+ replies = ["15169|8.8.8.0/24|US|arin|"];
+ },
+ {
+ name = "8.8.8.8.asn.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.10.asn.rspamd.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.10.asn.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.11.asn.rspamd.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.11.asn.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "test.com",
+ type = "txt";
+ replies = [""];
+ },
+ {
+ name = "other.com",
+ type = "txt";
+ rcode = 'norec';
+ },
+ {
+ name = "bob",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "mail.highsecure.ru",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "mail.highsecure.ru",
+ type = "a";
+ replies = ["88.99.142.95"];
+ },
+ {
+ name = "4.3.2.1.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "4.3.2.1.asn.rspamd.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "1.0.0.127.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "114.47.228.46.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "114.47.228.46.asn.rspamd.com",
+ type = "txt";
+ replies = ["34010|46.228.40.0/21|GB|ripencc|"];
+ },
+ {
+ name = "10.0.1.10.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.11.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "other.org",
+ type = "txt";
+ rcode = 'norec';
+ },
+ {
+ name = "8.8.8.8.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "rspamd.tk",
+ type = "txt";
+ replies = ["bio=a263adeab8acdcdb8b89e127b67d696061fdfbee"];
+ },
+ {
+ name = "fail1.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 redirect=www.dnssec-failed.org"];
+ },
+ {
+ name = "www.dnssec-failed.org",
+ type = "txt";
+ rcode = 'timeout';
+ },
+ {
+ name = "www.dnssec-failed.org",
+ type = "mx";
+ rcode = 'timeout';
+ },
+ {
+ name = "www.dnssec-failed.org",
+ type = "a";
+ rcode = 'timeout';
+ },
+ {
+ name = "www.dnssec-failed.org",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "cacophony.za.org",
+ type = "txt";
+ replies = ["v=spf1 redirect=asdfsfewewrredfs"];
+ },
+ {
+ name = "fail9.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 mx:www.dnssec-failed.org -all"];
+ },
+ {
+ name = "fail8.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 a:www.dnssec-failed.org -all"];
+ },
+ {
+ name = "1.2.3.4.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "2.2.3.4.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.10"];
+ },
+ {
+ name = "3.2.3.4.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.2", "127.0.0.3"];
+ },
+ {
+ name = "4.2.3.4.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "4.2.3.4.fake.wl";
+ type = "a";
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "4.3.2.1.fake.rbl";
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "131.193.18.151.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.3"];
+ },
+ # SURBL tests
+ {
+ name = "rciuosbadgpq6b5wt436nhgnwzmfh9w9.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ # testtest.com
+ name = "rcf1ecxtxrrpfncqzsdaiezjkf7f1rzz.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "jhcszdsmo3wuj5mp8t38kdisdmr3ib3q.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "g9ifs3q39oh5jwru94cj7ffaqd6rfyq6.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "xn--80arbjktj.xn--p1ai.test2.uribl";
+ type = a;
+ replies = ["127.0.1.2"];
+ },
+ {
+ name = "мойсайт.рф.test2.uribl";
+ type = a;
+ replies = ["127.0.1.2"];
+ },
+ {
+ name = "user.emailbl.com.test5.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "user.subdomain.emailbl.com.test5.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "baddomain.com.test6.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "user.subdomain.baddomain.com.test5.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "example.com.test2.uribl";
+ type = a;
+ replies = ["127.0.1.2"];
+ },
+ {
+ name = "user.example.com.test2.uribl";
+ type = a;
+ replies = ["127.0.1.5"];
+ },
+ {
+ name = "example.net.test2.uribl";
+ type = a;
+ replies = ["127.0.1.4"];
+ },
+ {
+ name = "rspamd.tk.test2.uribl";
+ type = a;
+ replies = ["127.0.1.4"];
+ },
+ {
+ name = "example.org.test3.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "example.ru.test3.uribl";
+ type = a;
+ replies = ["127.0.0.12"];
+ },
+ {
+ name = "example.ru";
+ type = a;
+ replies = ["8.8.8.8", "8.8.8.9"];
+ },
+ {
+ name = "8.8.8.8.test4.uribl";
+ type = a;
+ replies = ["127.0.0.4", "127.0.0.11"];
+ },
+ {
+ name = "uppht14nj4fsoycu3huctg9d5psx9je4.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "rspamd-test.com.test2.uribl";
+ type = a;
+ replies = ["127.0.1.2"];
+ },
+ {
+ name = "9.8.8.8.test4.uribl";
+ type = a;
+ replies = ["127.0.0.3"];
+ },
+ {
+ name = "4.very.dirty.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "clean.dirty.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "not.dirty.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "41.black.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "black.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "dirty.sanchez.com.test8.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "very.dirty.sanchez.com.test8.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "41.black.sanchez.com.test8.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "black.sanchez.com.test8.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "example.com.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "example.org.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "4.3.2.1.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "judo.za.org.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "12.11.10.9.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "8.7.6.5.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "8.8.8.8.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "site.resolveme",
+ type = "a";
+ replies = ["127.0.0.1"];
+ },
+ {
+ name = "not-resolvable.com",
+ type = "a";
+ rcode = 'norec';
+ },
+ # TODO: add IPv6 tests
+ ];
+ }
+}
+
+phishing {
+ symbol = "PHISHING";
+ strict_domains = {
+ STRICT_PHISHING = [
+ "{= env.TESTDIR =}/configs/maps/strict.phishing",
+ ];
+ STRICTER_PHISHING = [
+ "{= env.TESTDIR =}/configs/maps/stricter.phishing"
+ ]
+ }
+}
+
+redis {
+ servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}";
+ expand_keys = true;
+}
+
+regexp {
+ CONFIG_SELECTOR_RE_RCPT_SUBJECT {
+ re = 'test=/test@user.com some subject/$',
+ score = 100500,
+ }
+}
+
+spf {
+ external_relay = [
+ "{= env.TESTDIR =}/configs/maps/external_relay_ip.list",
+ ];
+}
+
+symbols {
+ FOUR_POINTS = {
+ score = 4.0,
+ }
+ SYM1 = {
+ score = 1.0,
+ }
+}
+
+worker "controller" {
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}";
+ keypair {
+ pubkey = "{= env.KEY_PUB1 =}";
+ privkey = "{= env.KEY_PVT1 =}";
+ }
+}
+
+worker "normal" {
+ count = 1;
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}";
+ keypair {
+ pubkey = "{= env.KEY_PUB1 =}";
+ privkey = "{= env.KEY_PVT1 =}";
+ }
+}
diff --git a/test/functional/configs/merged-override.conf b/test/functional/configs/merged-override.conf
new file mode 100644
index 0000000..09ac005
--- /dev/null
+++ b/test/functional/configs/merged-override.conf
@@ -0,0 +1,435 @@
+antivirus {
+ clam {
+ attachments_only = false;
+ symbol = "CLAM_VIRUS";
+ type = "clamav";
+ servers = "127.0.0.1:{= env.PORT_CLAM =}";
+ }
+ fprot {
+ attachments_only = false;
+ symbol = "FPROT_VIRUS";
+ type = "fprot";
+ servers = "127.0.0.1:{= env.PORT_FPROT =}";
+ patterns {
+ FPROT_EICAR = "^EICAR_Test_File$";
+ }
+ }
+ fprot_duplicate {
+ prefix = "fp_dupe";
+ attachments_only = false;
+ symbol = "FPROT2_VIRUS_DUPLICATE_DEFAULT";
+ type = "fprot";
+ servers = "127.0.0.1:{= env.PORT_FPROT2_DUPLICATE =}";
+ patterns = [
+ {FPROT2_VIRUS_DUPLICATE_PATTERN = "^E"},
+ {FPROT2_VIRUS_DUPLICATE_NOPE1 = "^EI",
+ FPROT2_VIRUS_DUPLICATE_NOPE2 = "^EIC",
+ FPROT2_VIRUS_DUPLICATE_NOPE3 = "^EICA",
+ FPROT2_VIRUS_DUPLICATE_NOPE4 = "^EICAR",
+ FPROT2_VIRUS_DUPLICATE_NOPE5 = "^EICAR_"}
+ ];
+ }
+ avast {
+ attachments_only = false;
+ symbol = "AVAST_VIRUS";
+ type = "avast";
+ servers = "127.0.0.1:{= env.PORT_AVAST =}";
+ }
+}
+
+multimap {
+ DNSBL_MAP {
+ type = "dnsbl";
+ map = "rspamd.com";
+ }
+ IP_MAP {
+ type = "ip";
+ map = "{= env.TESTDIR =}/configs/maps/ip.list";
+ }
+ FROM_MAP {
+ type = "from";
+ filter = "email:domain";
+ map = "{= env.TESTDIR =}/configs/maps/domains.list";
+ }
+ FREEMAIL_CC {
+ type = "header";
+ header = "Cc";
+ filter = "email:domain";
+ map = "{= env.TESTDIR =}/configs/maps/domains.list.2";
+ score = 1.0;
+ }
+ REGEXP_MAP {
+ type = "from";
+ filter = "email:addr";
+ regexp = true;
+ map = "{= env.TESTDIR =}/configs/maps/regexp.list";
+ }
+ DEPS_MAP {
+ type = "from";
+ filter = "email:addr";
+ regexp = true;
+ map = "{= env.TESTDIR =}/configs/maps/regexp.list";
+ require_symbols = "(R_SPF_ALLOW|R_SPF_DNSFAIL) & REGEXP_MAP & !FROM_MAP";
+ }
+ RCPT_DOMAIN {
+ type = "rcpt";
+ filter = "email:domain";
+ map = "{= env.TESTDIR =}/configs/maps/domains.list";
+ }
+ RCPT_USER {
+ type = "rcpt";
+ filter = "email:user";
+ map = "{= env.TESTDIR =}/configs/maps/users.list";
+ }
+ RCPT_MAP {
+ type = "rcpt";
+ filter = "email:addr";
+ symbols = ["SYM1"];
+ map = "{= env.TESTDIR =}/configs/maps/multiple.list";
+ score = 1.0;
+ }
+ RCPT_MAP_NOMULTISYM {
+ type = "rcpt";
+ filter = "email:addr";
+ disable_multisymbol = true;
+ map = "{= env.TESTDIR =}/configs/maps/multiple.list";
+ score = 1.0;
+ }
+ HEADER_MAP {
+ type = "header";
+ header = "To";
+ filter = "email:name";
+ map = "{= env.TESTDIR =}/configs/maps/utf.list";
+ regexp = true;
+ }
+ HOSTNAME_MAP {
+ type = "hostname";
+ map = "{= env.TESTDIR =}/configs/maps/domains.list";
+ }
+ HOSTNAME_TOP_MAP {
+ type = "hostname";
+ filter = "top";
+ map = "{= env.TESTDIR =}/configs/maps/top.list";
+ }
+ CDB_HOSTNAME {
+ type = "hostname";
+ map = "cdb://{= env.TESTDIR =}/configs/maps/domains.cdb";
+ }
+ REDIS_HOSTNAME {
+ type = "hostname";
+ map = "redis://hostname";
+ }
+ REDIS_HOSTNAME_EXPANSION {
+ type = "hostname";
+ map = "redis://${ip}.${principal_recipient_domain}";
+ }
+ REDIS_IPADDR {
+ type = "ip";
+ map = "redis://ipaddr";
+ }
+ REDIS_FROMADDR {
+ type = "from";
+ filter = "email:addr";
+ map = "redis://emailaddr";
+ }
+ REDIS_URL_TLD {
+ type = "url";
+ map = "redis://hostname";
+ filter = "tld";
+ }
+ REDIS_URL_RE_FULL {
+ type = "url";
+ map = "redis://fullurlre";
+ filter = "full:regexp:/(html)$/";
+ }
+ REDIS_URL_FULL {
+ type = "url";
+ map = "redis://fullurl";
+ filter = "full";
+ }
+ REDIS_URL_PHISHED {
+ type = "url";
+ map = "redis://phishedurl";
+ filter = "is_phished";
+ }
+ REDIS_URL_RE_TLD {
+ type = "url";
+ map = "redis://tldre";
+ filter = "tld:regexp:/(net)$/";
+ }
+ REDIS_URL_RE_PLAIN {
+ type = "url";
+ map = "redis://urlre";
+ filter = "regexp:/^(www)/";
+ }
+ REDIS_URL_NOFILTER {
+ type = "url";
+ map = "redis://urlnofilter";
+ }
+ REDIS_COUNTRY {
+ type = "country";
+ map = "redis://cc";
+ }
+ REDIS_ASN {
+ type = "asn";
+ map = "redis://asn";
+ }
+ REDIS_ASN_FILTERED {
+ type = "mempool";
+ variable = "asn";
+ map = "redis://asn";
+ filter = "regexp:/^([0-9]).*/";
+ }
+ RCVD_TEST_01 {
+ type = "received";
+ max_pos = 1;
+ map = "{= env.TESTDIR =}/configs/maps/rcvd.list";
+ }
+ RCVD_TEST_02 {
+ type = "received";
+ min_pos = -1;
+ map = "{= env.TESTDIR =}/configs/maps/rcvd.list";
+ }
+ RCVD_TEST_REDIS_01 {
+ type = "received";
+ map = "redis://RCVD_TEST";
+ }
+ RCVD_AUTHED_ONE {
+ type = "received";
+ map = "{= env.TESTDIR =}/configs/maps/rcvd2.list";
+ flags = ["authenticated"];
+ nflags = ["ssl"];
+ }
+ RCVD_AUTHED_TWO {
+ type = "received";
+ map = "{= env.TESTDIR =}/configs/maps/rcvd2.list";
+ flags = ["authenticated", "ssl"];
+ }
+ COMBINED_MAP_AND {
+ type = "combined";
+ rules {
+ ip = {
+ type = "radix";
+ map = "{= env.TESTDIR =}/configs/maps/ip.list";
+ selector = "ip";
+ }
+ from {
+ map = "{= env.TESTDIR =}/configs/maps/domains.list";
+ selector = "from:domain";
+ }
+ }
+ expression = "from & ip";
+ score = 10;
+ action = "no action"
+ }
+ COMBINED_MAP_OR {
+ type = "combined";
+ rules {
+ ip = {
+ type = "radix";
+ map = "{= env.TESTDIR =}/configs/maps/ip.list";
+ selector = "ip";
+ }
+ from {
+ map = "{= env.TESTDIR =}/configs/maps/domains.list";
+ selector = "from:domain";
+ }
+ }
+ expression = "from || ip"
+ }
+
+ EXTERNAL_MULTIMAP {
+ type = "hostname";
+ filter = "top";
+ map = {
+ external = true;
+ backend = "http://127.0.0.1:18080/map-query",
+ method = "query",
+ }
+ }
+
+ DYN_MULTIMAP {
+ type = "hostname";
+ map = "{= env.TESTDIR =}/configs/maps/dynamic_symbols.map";
+ dynamic_symbols = true;
+ }
+}
+
+rbl {
+ rbls {
+ fake {
+ from = true;
+ ipv4 = true;
+ ipv6 = true;
+ rbl = "fake.rbl";
+ symbol = "FAKE_RBL_UNKNOWN";
+ received = true;
+ symbols_prefixes = {
+ received = 'FAKE_RECEIVED_RBL',
+ from = 'FAKE_RBL',
+ }
+ unknown = true;
+ returncodes_matcher = "regexp";
+ returncodes = {
+ "CODE_2" = '^127\.0\.0\.2$';
+ "CODE_3" = '^127\.0\.0\.3$';
+ }
+ }
+ fake_whitelist {
+ from = true;
+ ipv4 = true;
+ ipv6 = true;
+ received = true;
+ is_whitelist = true;
+ rbl = "fake.wl";
+ symbol = "FAKE_WL_RBL_UNKNOWN";
+ unknown = true;
+ #returncodes_matcher = "luapattern";
+ returncodes = {
+ "FAKE_WL_RBL_CODE_2" = "127%.0%.0%.2";
+ "FAKE_WL_RBL_CODE_3" = "127%.0%.0%.3";
+ }
+ }
+ RSPAMD_EMAILBL {
+ rbl = "test8.uribl";
+ url_compose_map = "{= env.TESTDIR =}/configs/maps/url_compose_map_for_mails.list";
+ ignore_defaults = true;
+ emails = true;
+ emails_domainonly = true
+ returncodes_matcher = "radix";
+ returncodes = {
+ RSPAMD_EMAILBL = "127.0.0.2/32";
+ }
+ }
+ URIBL_NUMERIC {
+ checks = ["numeric_urls"];
+ rbl = "test9.uribl";
+ }
+ URIBL_NUMERIC_IMAGES {
+ checks = ["numeric_urls"];
+ images = true;
+ rbl = "test9.uribl";
+ }
+ UNKNOWN_URIBL_NUMERIC_CONTENT {
+ checks = ["numeric_urls"];
+ content_urls = true;
+ rbl = "test9.uribl";
+ returncodes_matcher = "glob";
+ returncodes = {
+ URIBL_NUMERIC_CONTENT = "*.*.*.*";
+ }
+ }
+ URIBL_NUMERIC_EVERYTHING {
+ checks = ["numeric_urls"];
+ images = true;
+ content_urls = true;
+ rbl = "test9.uribl";
+ exclude_local = false;
+ }
+ URIBL_NOCONTENT {
+ rbl = "test9.uribl";
+ ignore_defaults = true;
+ urls = true;
+ }
+ URIBL_WITHCONTENT {
+ rbl = "test9.uribl";
+ ignore_defaults = true;
+ urls = true;
+ content_urls = true;
+ }
+ URIBL_CONTENTONLY {
+ rbl = "test9.uribl";
+ ignore_defaults = true;
+ content_urls = true;
+ no_ip = true;
+ }
+ RBL_SELECTOR_SINGLE {
+ rbl = "test9.uribl";
+ ignore_defaults = true;
+ selector = "helo()";
+ }
+ RBL_SELECTOR_MULTIPLE {
+ rbl = "test9.uribl";
+ ignore_defaults = true;
+ selector = {
+ sel_from = "from('smtp'):domain";
+ sel_helo = "helo()";
+ }
+ }
+ }
+}
+
+surbl {
+ "whitelist" = [
+ "rspamd-test.com"
+ ];
+ rules {
+ "RSPAMD_URIBL" {
+ suffix = "test.uribl";
+ check_dkim = true;
+ check_emails = true;
+ images = false;
+ process_script =<<EOD
+function(url, suffix)
+ local cr = require "rspamd_cryptobox_hash"
+ local h = cr.create(url):base32():sub(1, 32)
+ return string.format("%s.%s", h, suffix)
+end
+EOD;
+ }
+ "DBL" {
+ suffix = "test2.uribl";
+ no_ip = true;
+ check_emails = true;
+ check_dkim = true;
+ ips = {
+ # spam domain
+ DBL_SPAM = "127.0.1.2";
+ # phish domain
+ DBL_PHISH = "127.0.1.4";
+ }
+ }
+ "URIBL_MULTI" {
+ suffix = "test3.uribl";
+ check_dkim = true;
+ check_emails = true;
+ bits {
+ URIBL_BLOCKED = 1;
+ URIBL_BLACK = 2;
+ URIBL_GREY = 4;
+ URIBL_RED = 8;
+ }
+ }
+ "SPAMHAUS_ZEN_URIBL" {
+ suffix = "test4.uribl";
+ resolve_ip = true;
+ check_emails = true;
+ ips {
+ URIBL_SBL = "127.0.0.2";
+ URIBL_SBL_CSS = "127.0.0.3";
+ URIBL_XBL = ["127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7"];
+ URIBL_PBL = ["127.0.0.10", "127.0.0.11"];
+ URIBL_DROP = "127.0.0.9";
+ }
+ }
+ "RSPAMD_URIBL_IMAGES" {
+ suffix = "test.uribl";
+ check_dkim = true;
+ check_emails = false;
+ images = true;
+ process_script =<<EOD
+ function(url, suffix)
+ local cr = require "rspamd_cryptobox_hash"
+ local h = cr.create(url):base32():sub(1, 32)
+ return string.format("%s.%s", h, suffix)
+end
+EOD;
+ }
+ "BAD_SUBDOMAIN" {
+ suffix = "test7.uribl";
+ url_compose_map = "{= env.TESTDIR =}/configs/maps/url_compose_map.list";
+ check_dkim = true;
+ check_emails = false;
+ }
+ }
+}
diff --git a/test/functional/configs/merged.conf b/test/functional/configs/merged.conf
new file mode 100644
index 0000000..0718d02
--- /dev/null
+++ b/test/functional/configs/merged.conf
@@ -0,0 +1,39 @@
+.include "{= env.TESTDIR =}/../../conf/rspamd.conf"
+
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua"
+
+# 101_lua
+lua = "{= env.TESTDIR =}/lua/conditions.lua"
+lua = "{= env.TESTDIR =}/lua/hashes.lua"
+lua = "{= env.TESTDIR =}/lua/maps_kv.lua"
+lua = "{= env.TESTDIR =}/lua/option_order.lua"
+lua = "{= env.TESTDIR =}/lua/recipients.lua"
+lua = "{= env.TESTDIR =}/lua/remove_result.lua"
+lua = "{= env.TESTDIR =}/lua/tlds.lua"
+
+# 104_get_from
+lua = "{= env.TESTDIR =}/lua/get_from.lua"
+
+# 240_redis
+lua = "{= env.TESTDIR =}/lua/redis.lua"
+
+# 250_dns
+lua = "{= env.TESTDIR =}/lua/dns.lua"
+
+# 270_selector
+lua = "{= env.TESTDIR =}/lua/selector_test.lua"
+
+# 281_fnames
+lua = "{= env.TESTDIR =}/lua/test_fname.lua"
+
+# 310_udp
+lua = "{= env.TESTDIR =}/lua/udp.lua"
+
+# 350_magic
+lua = "{= env.TESTDIR =}/lua/magic.lua"
+
+# 380_external_relay
+lua = "{= env.TESTDIR =}/lua/external_relay.lua"
+
+.include(priority=1,duplicate=merge) "{= env.TESTDIR =}/configs/merged-local.conf"
+.include(priority=2,duplicate=replace) "{= env.TESTDIR =}/configs/merged-override.conf"
diff --git a/test/functional/configs/milter.conf b/test/functional/configs/milter.conf
new file mode 100644
index 0000000..dc623c8
--- /dev/null
+++ b/test/functional/configs/milter.conf
@@ -0,0 +1,61 @@
+options = {
+ filters = ["spf", "dkim", "regexp"]
+ url_tld = "{= env.URL_TLD =}"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ lua_path = "{= env.INSTALLROOT =}/share/rspamd/lib/?.lua";
+ gtube_patterns = "all";
+ dns {
+ nameserver = ["8.8.8.8", "8.8.4.4"];
+ retransmits = 10;
+ timeout = 2s;
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+}
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ task_timeout = 60s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+worker {
+ type = "rspamd_proxy";
+ count = 1;
+ timeout = 120;
+ upstream {
+ local {
+ hosts = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}";
+ default = true;
+ }
+ }
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_PROXY =}";
+ milter = true;
+}
+modules {
+ path = "{= env.TESTDIR =}/../../src/plugins/lua/"
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+lua = "{= env.INSTALLROOT =}/share/rspamd/rules/rspamd.lua"
+lua = "{= env.TESTDIR =}/lua/params.lua"
+milter_headers {
+ extended_spam_headers = true;
+ skip_local = false;
+ skip_authenticated = false;
+}
diff --git a/test/functional/configs/neural.conf b/test/functional/configs/neural.conf
new file mode 100644
index 0000000..62ff856
--- /dev/null
+++ b/test/functional/configs/neural.conf
@@ -0,0 +1,83 @@
+options = {
+ url_tld = "{= env.URL_TLD =}"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ lua_path = "{= env.INSTALLROOT =}/share/rspamd/lib/?.lua"
+ filters = [];
+ explicit_modules = ["settings"];
+}
+
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+ log_usec = true;
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ add_header = 50500,
+ }
+ unknown_weight = 1
+}
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ task_timeout = 10s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+
+modules {
+ path = "{= env.TESTDIR =}/../../src/plugins/lua/"
+}
+
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+
+neural {
+ rules {
+ SHORT {
+ train {
+ learning_rate = 0.001;
+ max_usages = 2;
+ spam_score = 1;
+ ham_score = -1;
+ max_trains = 10;
+ max_iterations = 250;
+ }
+ symbol_spam = "NEURAL_SPAM_SHORT";
+ symbol_ham = "NEURAL_HAM_SHORT";
+ ann_expire = 86400;
+ watch_interval = 0.5;
+ }
+ SHORT_PCA {
+ train {
+ learning_rate = 0.001;
+ max_usages = 2;
+ spam_score = 1;
+ ham_score = -1;
+ max_trains = 10;
+ max_iterations = 250;
+ }
+ symbol_spam = "NEURAL_SPAM_SHORT_PCA";
+ symbol_ham = "NEURAL_HAM_SHORT_PCA";
+ ann_expire = 86400;
+ watch_interval = 0.5;
+ max_inputs = 10;
+ }
+ }
+ allow_local = true;
+
+}
+redis {
+ servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}";
+ expand_keys = true;
+}
+
+lua = "{= env.TESTDIR =}/lua/neural.lua";
diff --git a/test/functional/configs/neural_noauto.conf b/test/functional/configs/neural_noauto.conf
new file mode 100644
index 0000000..e228da8
--- /dev/null
+++ b/test/functional/configs/neural_noauto.conf
@@ -0,0 +1,85 @@
+options = {
+ url_tld = "{= env.URL_TLD =}"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ lua_path = "{= env.INSTALLROOT =}/share/rspamd/lib/?.lua"
+ filters = [];
+ explicit_modules = ["settings"];
+}
+
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+ log_usec = true;
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ add_header = 50500,
+ }
+ unknown_weight = 1
+}
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ task_timeout = 10s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+
+modules {
+ path = "{= env.TESTDIR =}/../../src/plugins/lua/"
+}
+
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+
+neural {
+ rules {
+ SHORT {
+ train {
+ learning_rate = 0.001;
+ max_usages = 2;
+ spam_score = 1;
+ ham_score = -1;
+ max_trains = 10;
+ max_iterations = 250;
+ store_pool_only = true;
+ }
+ symbol_spam = "NEURAL_SPAM_SHORT";
+ symbol_ham = "NEURAL_HAM_SHORT";
+ ann_expire = 86400;
+ watch_interval = 0.5;
+ }
+ SHORT_PCA {
+ train {
+ learning_rate = 0.001;
+ max_usages = 2;
+ spam_score = 1;
+ ham_score = -1;
+ max_trains = 10;
+ max_iterations = 250;
+ store_pool_only = true;
+ }
+ symbol_spam = "NEURAL_SPAM_SHORT_PCA";
+ symbol_ham = "NEURAL_HAM_SHORT_PCA";
+ ann_expire = 86400;
+ watch_interval = 0.5;
+ max_inputs = 2;
+ }
+ }
+ allow_local = true;
+
+}
+redis {
+ servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}";
+ expand_keys = true;
+}
+
+lua = "{= env.TESTDIR =}/lua/neural.lua";
diff --git a/test/functional/configs/nginx.conf b/test/functional/configs/nginx.conf
new file mode 100644
index 0000000..9a27f49
--- /dev/null
+++ b/test/functional/configs/nginx.conf
@@ -0,0 +1,20 @@
+events {
+}
+worker_processes 1;
+pid ${RSPAMD_TMPDIR}/nginx.pid;
+error_log ${RSPAMD_TMPDIR}/error.log;
+http {
+ default_type application/octet-stream;
+ sendfile on;
+
+ server {
+ # no need for root privileges
+ listen ${NGINX_ADDR}:${NGINX_PORT};
+ server_name localhost;
+
+ location / {
+ root ${RSPAMD_TMPDIR};
+ autoindex on;
+ }
+ }
+}
diff --git a/test/functional/configs/p0f.conf b/test/functional/configs/p0f.conf
new file mode 100644
index 0000000..cb492f9
--- /dev/null
+++ b/test/functional/configs/p0f.conf
@@ -0,0 +1,13 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+redis {
+ servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}";
+}
+p0f {
+ socket = "{= env.P0F_SOCKET =}";
+ patterns {
+ WINDOWS = '^Windows.*';
+ ETHER = '^Ethernet.*';
+ DISTGE10 = '^distance:[0-9]{2}$';
+ }
+}
diff --git a/test/functional/configs/password.conf b/test/functional/configs/password.conf
new file mode 100644
index 0000000..27b88ee
--- /dev/null
+++ b/test/functional/configs/password.conf
@@ -0,0 +1,45 @@
+options = {
+ filters = ["spf", "dkim", "regexp"]
+ url_tld = "{= env.TESTDIR =}/../lua/unit/test_tld.dat"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ dns {
+ retransmits = 10;
+ timeout = 2s;
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+}
+
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ keypair {
+ pubkey = "{= env.KEY_PUB1 =}";
+ privkey = "{= env.KEY_PVT1 =}";
+ }
+ task_timeout = 60s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ keypair {
+ pubkey = "{= env.KEY_PUB1 =}";
+ privkey = "{= env.KEY_PVT1 =}";
+ }
+ password = {= env.PASSWORD =};
+ enable_password = {= env.ENABLE_PASSWORD =};
+ stats_path = "{= env.TMPDIR =}/stats.ucl";
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
diff --git a/test/functional/configs/plugins.conf b/test/functional/configs/plugins.conf
new file mode 100644
index 0000000..22190a3
--- /dev/null
+++ b/test/functional/configs/plugins.conf
@@ -0,0 +1,770 @@
+options = {
+ filters = [ "dkim", "regexp"]
+ url_tld = "{= env.URL_TLD =}"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ lua_path = "{= env.INSTALLROOT =}/share/rspamd/lib/?.lua"
+ explicit_modules = ["settings", "bayes_expiry"];
+ dns {
+ nameserver = ["8.8.8.8", "8.8.4.4"];
+ retransmits = 10;
+ timeout = 2s;
+ fake_records = [{ # ed25519
+ name = "test._domainkey.example.com";
+ type = txt;
+ replies = ["k=ed25519; p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y="];
+ },
+ {
+ name = "brisbane._domainkey.football.example.com";
+ type = txt;
+ replies = ["v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo="];
+ },
+ {
+ name = "test._domainkey.football.example.com";
+ type = txt;
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkHlOQoBTzWRiGs5V6NpP3idY6Wk08a5qhdR6wy5bdOKb2jLQiY/J16JYi0Qvx/byYzCNb3W91y3FutACDfzwQ/BC/e/8uBsCR+yz1Lxj+PL6lHvqMKrM3rG4hstT5QjvHO9PzoxZyVYLzBfO2EeC3Ip3G+2kryOTIKT+l/K4w3QIDAQAB"],
+ },
+ {
+ name = "dkim._domainkey.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXtxBE5IiNRMcq2/lc2zErfdCvDFyQNBnMjbOjBQrPST2k4fdGbtpe5Iu5uS01Met+dAEf94XL8I0hwmYw+n70PP834zfJGi2egwGqrakpaWsCDPvIJZLkxJCJKQRA/zrQ622uEXdvYixVbsEGVw7U4wAGSmT5rU2eU1y63AlOlQIDAQAB"];
+ },
+ {
+ name = "eddsa._domainkey.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=ed25519; p=+nU+aC33ICeS4zx8VUjFYCtxj0fRbHWQn2gP2hTkm9w="];
+ },
+ {
+ name = "dkim._domainkey.invalid.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEEXmNGQq7PUrr9Mg4UakTFHgXBCy2DOztkrZm+0OrVWtiRzGluxBkbOWTBwuU3/Yw97yTphBMQxzWFN603/f/KPAQcF/Lc1l+6kmIBBxNXjjGuOK/3PYKZVntUdKmqcQBYfnHdzH2Tohbuyx1a7xqnv6VSChqQrZU4CwkeT3+eQIDAQAB"];
+ },
+ {
+ name = "eddsa._domainkey.invalid.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=ed25519; p=Wkkrp5DJTvknDMGWYv8vm3p3sZjiQp03LZo80RregY8="];
+ },
+ {
+ name = "dkim._domainkey.rspamd.com",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCd/XhZBEGGAss48lEuMmwZv9lOFf6FTllBiQ3sPhdTpDdIPaW9TInW7iYnYD/bXHeVxYAyD/sKhYk6+qGBRu10rEi+iyPvLCIED+Boq0tEQosuKuV6Fjoomb+QhZY9KdjyZTjsrFPZ+wCkUY/30uTmpX2SwSqyxxlK0pUIsRgMAQIDAQAB"];
+ },
+ {
+ name = "_dmarc.rspamd.com",
+ type = "txt";
+ rcode = 'norec';
+ },
+ {
+ name = "dkim._domainkey.highsecure.ru",
+ type = "txt";
+ replies = ["p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK4ZQYky30GH0Ak9OQ1fv3IdFNbpOtpa4S/PR20ZLgPXfd/FCA//ztUmu7kHlELI+/+4f8W+xX0oZlOc/cFxhopRjXZMlSsQqmWOZ40/GxWFBtcqafKu78FCqO7URqZUmMCM5Jlp4zt/yzH3dbYNG3i5PVlB5QtQnZvY+dvBL3dwIDAQAB"];
+ },
+ {
+ name = "_dmarc.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=none; sp=reject"];
+ },
+ {
+ name = "_dmarc.my.mom.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject"];
+ },
+ {
+ name = "example.net",
+ type = "txt";
+ replies = ["v=spf1 -all"];
+ },
+ {
+ name = "fail4.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 redirect=asdfsfewewrredfs"];
+ },
+ {
+ name = "_dmarc.reject.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject"];
+ },
+ {
+ name = "spf.cacophony.za.org",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.4.4 -all"];
+ },
+ {
+ name = "fail7.org.org.za",
+ type = "a";
+ rcode = 'norec';
+ },
+ {
+ name = "fail6.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 mx -all"];
+ },
+ {
+ name = "fail6.org.org.za",
+ type = "mx";
+ rcode = 'norec';
+ },
+ {
+ name = "fail7.org.org.za",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "_dmarc.quarantine.cacophony.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=quarantine"];
+ },
+ {
+ name = "_dmarc.yo.mom.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject; aspf=s; adkim=s;"];
+ },
+ {
+ name = "yo.mom.za.org",
+ type = "txt";
+ replies = ["v=spf1 ip4:37.48.67.26 -all"];
+ },
+ {
+ name = "testdkim._domainkey.mom.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3v4VPE1QMHUzsMRbC8VzXNq82mDjiv9Gi1NB/YYC+vIYZT+sE/Uxnr0Clk8C2jgzEr3jcxgQEWZfMtEEg/EfEJvh4SrXWv9c0gw1EEfxKxX9i+r8yBQtc/EWospWVDkhF2lAvQAK1lV1ZiU7psJ6fh1CI39uZyWdAktZzWLf0zQIDAQAB"];
+ },
+ {
+ name = "_dmarc.rspamd.tk",
+ type = "txt";
+ replies = ["bio=a263adeab8acdcdb8b89e127b67d696061fdfbee"];
+ },
+ # For unknown dkim tags
+ {
+ name = "18457.62be233b.k2206._domainkey.taugh.com";
+ type = "txt";
+ replies = ["v=DKIM1; h=sha256; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvLwxxLlZJ+uU3SctsQ2pjq6K0xyjhmvlIfWWGxRLxVpwyLPaNCUJNDnP0d0Fk+HQXub1T6R22T79L9yGQEZuHrD8MxchBKO++ywk7HOd1LvhweeKPUiXD03Dda54svQ2hnT7MQBFU92CWXoD0BRs9QPMyCC2QiZk0IwB1rK9sClOCjOdOH1mT1Oz8XObUqT3Nd6Oi7LSppyoMzYg4TEkmyiz0c34uiXOkqZwonf2V6+s/v/1/fz4dH6hgnn2cHLnjGmzmiKQgs8lJNMjhfI4sIzg26xNb4wCTVlggP6zDr7lxe9DZuTRcP5/tSI6ihDO/zc+7HmG83EIkqgqllI6IQIDAQAB ; n=Signing=20key=20at=20https://www.iecc.com/dkimkeys/k2206 ;"];
+ },
+ {
+ name = "fail2.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.4.4 include:www.dnssec-failed.org -all"];
+ },
+ {
+ name = "fail3.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 include:total.barf -all"];
+ },
+ {
+ name = "mom.za.org",
+ type = "txt";
+ replies = ["v=spf1 ip4:37.48.67.26 -all"];
+ },
+ {
+ name = "testdkim._domainkey.asdf.rspamd.tk", # testdkim._domainkey.asdf.rspamd.tk is an alias for rspamd.tk
+ type = "txt";
+ replies = ["bio=a263adeab8acdcdb8b89e127b67d696061fdfbee"];
+ },
+ {
+ name = "testdkim._domainkey.rspamd.tk", # testdkim._domainkey.rspamd.tk is an alias for rspamd.tk
+ type = "txt";
+ replies = ["bio=a263adeab8acdcdb8b89e127b67d696061fdfbee"];
+ },
+ {
+ name = "pass1.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 include:pass2.org.org.za -all"];
+ },
+ {
+ name = "95.142.99.88.in-addr.arpa",
+ type = "ptr";
+ replies = ["mail.highsecure.ru"];
+ },
+ {
+ name = "mail.highsecure.ru",
+ type = "a";
+ replies = ["88.99.142.95"];
+ },
+ {
+ name = "mail.highsecure.ru",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "1.0.66.128.in-addr.arpa",
+ type = "ptr";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "182.216.85.209.in-addr.arpa",
+ type = "ptr";
+ replies = ["mail-qt0-f182.google.com"];
+ },
+ {
+ name = "crazyspf.cacophony.za.org",
+ type = "txt";
+ replies = ["v=spf1 ptr:cacophony.za.org ptr:rspamd.com ptr:yahoo.com ptr:yahoo.net ptr:highsecure.ru -all"];
+ },
+ {
+ name = "pass2.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 -all"];
+ },
+ {
+ name = "_dmarc.yoni.za.org",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject; sp=none;"];
+ },
+ {
+ name = "fail10.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 redirect=fail5.org.org.za"];
+ },
+ {
+ name = "fail11.org.org.za",
+ type = "txt";
+ replies = ["v=sPF1 ip4:8.8.8.8 -all"];
+ },
+ {
+ name = "fail5.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 OMGBARF"];
+ },
+ {
+ name = "fail7.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 a -all"];
+ },
+ {
+ name = "trusted.com",
+ type = "txt";
+ replies = ["v=spf1 ip4:192.168.1.1"];
+ },
+ {
+ name = "external.com",
+ type = "txt";
+ replies = ["v=spf1 ip4:37.48.67.26"];
+ },
+ {
+ name = "co.za",
+ type = "txt";
+ rcode = 'norec';
+ },
+ {
+ name = "testdkim1._domainkey.yoni.za.org",
+ type = "txt";
+ replies = ["v=DKIM1; k=rsa; p=BARF"];
+ },
+ {
+ name = "_dmarc.yoni.za.net",
+ type = "txt";
+ replies = ["v=DMARC1; p=none; sp=quarantine"];
+ },
+ {
+ name = "za",
+ type = "txt";
+ replies = ["Top-level domain for South Africa"];
+ },
+ {
+ name = "_dmarc.foo.yoni.za.org",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.foo.cacophony.za.org",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.foo.yoni.za.net",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.dnssec-failed.org",
+ type = "txt";
+ rcode = 'timeout';
+ },
+ {
+ name = "_dmarc.example.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.zero_pct.com",
+ type = "txt";
+ replies = ["v=DMARC1; p=reject; sp=quarantine; pct=0"];
+ },
+ {
+ name = "example.com",
+ type = "txt";
+ replies = ["$Id: example.com 4415 2015-08-24 20:12:23Z davids $", "v=spf1 -all"];
+ },
+ {
+ name = "example.com",
+ type = "a";
+ replies = ["93.184.216.34"];
+ },
+ {
+ name = "testdkim1._domainkey.dnssec-failed.org",
+ type = "txt";
+ rcode = 'timeout';
+ },
+ {
+ name = "total.barf",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "_dmarc.foo.cacophony.za.org",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "zzzzaaaa",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "asdfsfewewrredfs",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "95.142.99.88.asn.rspamd.com",
+ type = "txt";
+ replies = ["24940|88.99.0.0/16|DE|ripencc|"];
+ },
+ {
+ name = "2.a.d.1.1.d.e.f.f.f.0.0.4.5.0.5.d.6.2.0.6.b.a.a.8.c.7.0.1.0.a.2.asn6.rspamd.com",
+ type = "txt";
+ replies = ["20857|2a01:7c8::/32|NL|ripencc|"];
+ },
+ {
+ name = "2.a.d.1.1.d.e.f.f.f.0.0.4.5.0.5.d.6.2.0.6.b.a.a.8.c.7.0.1.0.a.2.rspamd.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "2.a.d.1.1.d.e.f.f.f.0.0.4.5.0.5.d.6.2.0.6.b.a.a.8.c.7.0.1.0.a.2.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "rspamd.com",
+ type = "txt";
+ replies = ["v=spf1 mx -all"];
+ },
+ {
+ name = "rspamd.com",
+ type = "mx";
+ replies = ["10 mail.highsecure.ru"];
+ },
+ {
+ name = "95.142.99.88.rspamd.com",
+ type = "a";
+ rcode = 'norec';
+ },
+ {
+ name = "95.142.99.88.rspamd.com",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "2.0.0.127.rspamd.com",
+ type = "a";
+ replies = ["127.0.0.1"];
+ },
+ {
+ name = "8.8.8.8.asn.rspamd.com",
+ type = "txt";
+ replies = ["15169|8.8.8.0/24|US|arin|"];
+ },
+ {
+ name = "8.8.8.8.asn.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.10.asn.rspamd.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.10.asn.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.11.asn.rspamd.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.11.asn.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "test.com",
+ type = "txt";
+ replies = [""];
+ },
+ {
+ name = "other.com",
+ type = "txt";
+ rcode = 'norec';
+ },
+ {
+ name = "bob",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "mail.highsecure.ru",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "mail.highsecure.ru",
+ type = "a";
+ replies = ["88.99.142.95"];
+ },
+ {
+ name = "4.3.2.1.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "4.3.2.1.asn.rspamd.com",
+ type = "txt";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "1.0.0.127.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "114.47.228.46.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "114.47.228.46.asn.rspamd.com",
+ type = "txt";
+ replies = ["34010|46.228.40.0/21|GB|ripencc|"];
+ },
+ {
+ name = "10.0.1.10.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "10.0.1.11.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "other.org",
+ type = "txt";
+ rcode = 'norec';
+ },
+ {
+ name = "8.8.8.8.rspamd.com",
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "rspamd.tk",
+ type = "txt";
+ replies = ["bio=a263adeab8acdcdb8b89e127b67d696061fdfbee"];
+ },
+ {
+ name = "fail1.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 redirect=www.dnssec-failed.org"];
+ },
+ {
+ name = "www.dnssec-failed.org",
+ type = "txt";
+ rcode = 'timeout';
+ },
+ {
+ name = "www.dnssec-failed.org",
+ type = "mx";
+ rcode = 'timeout';
+ },
+ {
+ name = "www.dnssec-failed.org",
+ type = "a";
+ rcode = 'timeout';
+ },
+ {
+ name = "www.dnssec-failed.org",
+ type = "aaaa";
+ rcode = 'norec';
+ },
+ {
+ name = "cacophony.za.org",
+ type = "txt";
+ replies = ["v=spf1 redirect=asdfsfewewrredfs"];
+ },
+ {
+ name = "fail9.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 mx:www.dnssec-failed.org -all"];
+ },
+ {
+ name = "fail8.org.org.za",
+ type = "txt";
+ replies = ["v=spf1 ip4:8.8.8.8 a:www.dnssec-failed.org -all"];
+ },
+ {
+ name = "1.2.3.4.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "2.2.3.4.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.10"];
+ },
+ {
+ name = "3.2.3.4.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.2", "127.0.0.3"];
+ },
+ {
+ name = "4.2.3.4.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "4.2.3.4.fake.wl";
+ type = "a";
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "4.3.2.1.fake.rbl";
+ type = "a";
+ rcode = 'nxdomain';
+ },
+ {
+ name = "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "131.193.18.151.fake.rbl";
+ type = "a";
+ replies = ["127.0.0.3"];
+ },
+ # SURBL tests
+ {
+ name = "rciuosbadgpq6b5wt436nhgnwzmfh9w9.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ # testtest.com
+ name = "rcf1ecxtxrrpfncqzsdaiezjkf7f1rzz.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "jhcszdsmo3wuj5mp8t38kdisdmr3ib3q.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "g9ifs3q39oh5jwru94cj7ffaqd6rfyq6.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "xn--80arbjktj.xn--p1ai.test2.uribl";
+ type = a;
+ replies = ["127.0.1.2"];
+ },
+ {
+ name = "мойсайт.рф.test2.uribl";
+ type = a;
+ replies = ["127.0.1.2"];
+ },
+ {
+ name = "user.emailbl.com.test5.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "user.subdomain.emailbl.com.test5.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "baddomain.com.test6.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "user.subdomain.baddomain.com.test5.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "example.com.test2.uribl";
+ type = a;
+ replies = ["127.0.1.2"];
+ },
+ {
+ name = "user.example.com.test2.uribl";
+ type = a;
+ replies = ["127.0.1.5"];
+ },
+ {
+ name = "example.net.test2.uribl";
+ type = a;
+ replies = ["127.0.1.4"];
+ },
+ {
+ name = "rspamd.tk.test2.uribl";
+ type = a;
+ replies = ["127.0.1.4"];
+ },
+ {
+ name = "example.org.test3.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "example.ru.test3.uribl";
+ type = a;
+ replies = ["127.0.0.12"];
+ },
+ {
+ name = "example.ru";
+ type = a;
+ replies = ["8.8.8.8", "8.8.8.9"];
+ },
+ {
+ name = "8.8.8.8.test4.uribl";
+ type = a;
+ replies = ["127.0.0.4", "127.0.0.11"];
+ },
+ {
+ name = "uppht14nj4fsoycu3huctg9d5psx9je4.test.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "rspamd-test.com.test2.uribl";
+ type = a;
+ replies = ["127.0.1.2"];
+ },
+ {
+ name = "9.8.8.8.test4.uribl";
+ type = a;
+ replies = ["127.0.0.3"];
+ },
+ {
+ name = "4.very.dirty.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "clean.dirty.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "not.dirty.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "41.black.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "black.sanchez.com.test7.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "dirty.sanchez.com.test8.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "very.dirty.sanchez.com.test8.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "41.black.sanchez.com.test8.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "black.sanchez.com.test8.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "example.com.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "example.org.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ {
+ name = "8.8.8.8.test9.uribl";
+ type = a;
+ replies = ["127.0.0.2"];
+ },
+ # TODO: add IPv6 tests
+ ];
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+ log_usec = true;
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ add_header = 50500,
+ }
+ unknown_weight = 1
+}
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ task_timeout = 10s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+modules {
+ path = "{= env.TESTDIR =}/../../src/plugins/lua/"
+}
+spf {}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+lua = "{= env.INSTALLROOT =}/share/rspamd/rules/rspamd.lua";
diff --git a/test/functional/configs/proxy.conf b/test/functional/configs/proxy.conf
new file mode 100644
index 0000000..ff31eae
--- /dev/null
+++ b/test/functional/configs/proxy.conf
@@ -0,0 +1,26 @@
+options = {
+ filters = ["spf", "dkim", "regexp"]
+ url_tld = "{= env.URL_TLD =}"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ lua_path = "{= env.INSTALLROOT =}/share/rspamd/lib/?.lua"
+ dns {
+ nameserver = ["8.8.8.8", "8.8.4.4"];
+ retransmits = 10;
+ timeout = 2s;
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+}
+worker "rspamd_proxy" {
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_PROXY =}";
+ upstream {
+ name = "{= env.LOCAL_ADDR =}";
+ default = yes;
+ hosts = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}";
+ }
+ count = 1;
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
diff --git a/test/functional/configs/redis-server.conf b/test/functional/configs/redis-server.conf
new file mode 100644
index 0000000..0943025
--- /dev/null
+++ b/test/functional/configs/redis-server.conf
@@ -0,0 +1,7 @@
+bind ${RSPAMD_REDIS_ADDR}
+daemonize yes
+loglevel debug
+logfile ${RSPAMD_TMPDIR}/redis.log
+pidfile ${RSPAMD_TMPDIR}/redis.pid
+port ${RSPAMD_REDIS_PORT}
+dir ${RSPAMD_TMPDIR}
diff --git a/test/functional/configs/redis.conf b/test/functional/configs/redis.conf
new file mode 100644
index 0000000..8b3f0c4
--- /dev/null
+++ b/test/functional/configs/redis.conf
@@ -0,0 +1,7 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+lua = "{= env.LUA_SCRIPT =}";
+redis {
+ servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}";
+ expand_keys = true;
+}
diff --git a/test/functional/configs/regexp.conf b/test/functional/configs/regexp.conf
new file mode 100644
index 0000000..06f22c9
--- /dev/null
+++ b/test/functional/configs/regexp.conf
@@ -0,0 +1,64 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+regexp {
+ SA_BODY_WORD_BOUNDARY_ON_NEWLINE {
+ re = '/\bhello\s/{sa_body}',
+ score = 0.0,
+ description = 'Test if word boundary works correctly on sa_body regexes',
+ group = 'body',
+ }
+ SA_BODY_WORD {
+ re = '/hello/{sa_body}',
+ score = 0.0,
+ description = 'Test if regex works at all in sa_body',
+ group = 'body',
+ }
+ SA_BODY_WORD_WITH_NEWLINE {
+ re = '/helloworld/{sa_body}',
+ score = 0.0,
+ description = 'Test if regex matches word separated with newline (should not work!)',
+ group = 'body',
+ }
+ SA_BODY_WORD_WITH_SPACE {
+ re = '/hello world/{sa_body}',
+ score = 0.0,
+ description = 'Test if regex matches word separated with newline (should work - newline is replaced with space)',
+ group = 'body',
+ }
+ SA_BODY_WORD_WITH_SPACE_BOUNDARIES {
+ re = '/\bhello world\b/{sa_body}',
+ score = 0.0,
+ description = 'Test if regex matches word separated with newline (should work - newline is replaced with space)',
+ group = 'body',
+ }
+ SA_BODY_WORD_WITH_SPACE_BOUNDARIES_2 {
+ re = '/\shello\sworld\s/{sa_body}',
+ score = 0.0,
+ description = 'Test if regex matches word separated with newline (should work - newline is replaced with space)',
+ group = 'body',
+ }
+ SA_BODY_WORD_WITH_SPACE_BOUNDARIES_3 {
+ re = '/\shello\sworld\sthis\s/{sa_body}',
+ score = 0.0,
+ description = 'Test if regex matches word separated with newline (should work - newline is replaced with space)',
+ group = 'body',
+ }
+ SA_BODY_WORD_WITH_SPACE_AND_DOT {
+ re = '/\bword\.\sagain\b/{sa_body}',
+ score = 0.0,
+ description = 'Test if regex matches word separated with newline (should work - newline is replaced with space)',
+ group = 'body',
+ }
+}
+
+options {
+ dynamic_conf = "{= env.TESTDIR =}/configs/dynamic.conf";
+}
+dmarc { }
+spf { }
+dkim { }
+modules {
+ path = "{= env.TESTDIR =}/../../src/plugins/lua/"
+}
+
+lua = "{= env.TESTDIR =}/lua/regex_test.lua"
diff --git a/test/functional/configs/settings.conf b/test/functional/configs/settings.conf
new file mode 100644
index 0000000..506bde1
--- /dev/null
+++ b/test/functional/configs/settings.conf
@@ -0,0 +1,117 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+lua = "{= env.LUA_SCRIPT =}";
+
+settings {
+ id_test {
+ id = "id_test";
+ apply {
+ symbols_enabled = ["SIMPLE_TEST"];
+ }
+ }
+
+ id_pre { # implicit id
+ apply {
+ symbols_enabled = ["SIMPLE_PRE"];
+ }
+ }
+
+ id_virtual {
+ apply {
+ symbols_enabled = ["SIMPLE_VIRTUAL"];
+ }
+ }
+
+ id_virtual1 {
+ apply {
+ symbols {
+ EXPLICIT_VIRTUAL1 = 10.0
+ }
+ symbols_enabled = ["DEP_REAL"];
+ }
+ }
+
+ id_virtual_group {
+ user = "test@example.com";
+ from = "test2@example.com";
+ hostname = "example.com";
+ selector = "rcpts:addr.in(test3@example.com)";
+ header = {
+ "Content-Transfer-Encoding" = "7bit";
+ "Custom-Header" = true;
+ "Mime-Version" = false;
+ }
+ request_header = {
+ "Test" = "passed";
+ }
+
+ expression = 'user || from || hostname || selector:1 || header:mime_version || header:custom_header || header:content_transfer_encoding || request_header:test'
+ apply {
+ symbols_enabled {
+ SIMPLE_VIRTUAL = 10.0;
+ }
+ symbols {
+ EXPLICIT_VIRTUAL = 10.0
+ }
+ }
+ }
+
+ id_test_priority {
+ priority = high;
+ from = "user@test.com";
+ apply {
+ symbols_enabled {
+ PRIORITY = 10.0;
+ }
+ symbols {
+ PRIORITY_2 = 10.0
+ }
+ }
+ }
+
+ empty_symbols_enabled {
+ ip = "5.5.5.5";
+ apply {
+ symbols_enabled = [];
+ }
+ }
+
+ empty_groups_enabled {
+ selector = "ip.in(\"5.5.5.6\")";
+ apply {
+ groups_enabled = [];
+ }
+ }
+
+ external {
+ disabled = true
+ external_map = {
+ map = {
+ backend = "http://127.0.0.1:18080/settings";
+ external = true;
+ method = "body";
+ encode = "json";
+ }
+ selector = "id('from');from('mime')";
+ }
+ register_symbols = {
+ EXTERNAL_SETTINGS = { score = 1.0 }
+ }
+ }
+}
+
+classifier {
+ backend = "sqlite3";
+ statfile {
+ spam = true;
+ symbol = BAYES_SPAM;
+ path = "/tmp/bayes.spam.sqlite3";
+ }
+ statfile {
+ spam = false;
+ symbol = BAYES_HAM;
+ path = "/tmp/bayes.ham.sqlite3";
+ }
+ min_learns = 1;
+ min_token_hits = 1;
+}
diff --git a/test/functional/configs/spamassassin.conf b/test/functional/configs/spamassassin.conf
new file mode 100644
index 0000000..0b66951
--- /dev/null
+++ b/test/functional/configs/spamassassin.conf
@@ -0,0 +1,7 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+spamassassin {
+ rules = "{= env.TESTDIR =}/configs/spamassassin.rules"
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+lua = "{= env.TESTDIR =}/lua/simple.lua"
diff --git a/test/functional/configs/spamassassin.rules b/test/functional/configs/spamassassin.rules
new file mode 100644
index 0000000..614f85e
--- /dev/null
+++ b/test/functional/configs/spamassassin.rules
@@ -0,0 +1,97 @@
+# These rules are from SpamAssasin project! (but might be modified)
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ifplugin Mail::SpamAssassin::Plugin::FreeMail
+
+freemail_domains qq.com yahoo.com outlook.com
+freemail_domains lycosmail.com hotmail.com
+
+header FREEMAIL_FROM eval:check_freemail_from()
+describe FREEMAIL_FROM Sender email is commonly abused enduser mail provider
+score FREEMAIL_FROM 1.0
+
+header FREEMAIL_ENVFROM_END_DIGIT eval:check_freemail_header('EnvelopeFrom', '\d@')
+describe FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit
+score FREEMAIL_ENVFROM_END_DIGIT 1.0
+
+header FREEMAIL_SUBJECT eval:check_freemail_header('Subject')
+describe FREEMAIL_SUBJECT Subject contains freemail
+score FREEMAIL_SUBJECT 1.0
+
+endif
+
+ifplugin Mail::SpamAssassin::Plugin::WLBLEval
+
+header USER_IN_BLACKLIST eval:check_from_in_blacklist()
+describe USER_IN_BLACKLIST From: address is in the user's black-list
+tflags USER_IN_BLACKLIST userconf noautolearn
+score USER_IN_BLACKLIST 10.0
+
+header USER_IN_WHITELIST eval:check_from_in_whitelist()
+describe USER_IN_WHITELIST From: address is in the user's white-list
+tflags USER_IN_WHITELIST userconf nice noautolearn
+score USER_IN_WHITELIST -10.0
+
+header USER_IN_BLACKLIST_TO eval:check_to_in_blacklist()
+describe USER_IN_BLACKLIST_TO User is listed in 'blacklist_to'
+tflags USER_IN_BLACKLIST_TO userconf noautolearn
+score USER_IN_BLACKLIST_TO 10.0
+
+header USER_IN_WHITELIST_TO eval:check_to_in_whitelist()
+describe USER_IN_WHITELIST_TO User is listed in 'whitelist_to'
+tflags USER_IN_WHITELIST_TO userconf nice noautolearn
+score USER_IN_WHITELIST_TO -10.0
+
+# not implemented
+#header USER_IN_DEF_WHITELIST eval:check_from_in_default_whitelist()
+#describe USER_IN_DEF_WHITELIST From: address is in the default white-list
+#tflags USER_IN_DEF_WHITELIST userconf nice noautolearn
+#score USER_IN_DEF_WHITELIST -10.0
+
+# not implemented
+#header USER_IN_MORE_SPAM_TO eval:check_to_in_more_spam()
+#describe USER_IN_MORE_SPAM_TO User is listed in 'more_spam_to'
+#tflags USER_IN_MORE_SPAM_TO userconf nice noautolearn
+
+# not implemented
+#header USER_IN_ALL_SPAM_TO eval:check_to_in_all_spam()
+#describe USER_IN_ALL_SPAM_TO User is listed in 'all_spam_to'
+#tflags USER_IN_ALL_SPAM_TO userconf nice noautolearn
+
+blacklist_to xxx@example.com
+blacklist_from yy@example.com
+whitelist_from nasutkadqw@esumare.ru
+whitelist_to zelen@megafonkavkaz.ru
+# not implemented
+#whitelist_from example@example.net yy@example.com
+# not implemented
+#whitelist_from *@example.com
+# not implemented
+#whitelist_from_rcvd *@example.org
+# not implemented
+#def_whitelist_from rspamd.com
+endif
+
+# These rules are /not/ from SpamAssassin project
+
+header TEST_XFOO X-Foo =~ /.{1,50}/
+score TEST_XFOO 1
+header TEST_XBAR X-Bar =~ /.{1,50}/
+score TEST_XBAR 1
+meta TEST_META1 TEST_XFOO && TEST_XBAR
+meta TEST_META2 TEST_META1 && SIMPLE_TEST
+meta TEST_META3 TEST_META1 && TEST_META2
+meta TEST_META4 TEST_META3 && TEST_XBAR
diff --git a/test/functional/configs/stats.conf b/test/functional/configs/stats.conf
new file mode 100644
index 0000000..ba6a5fe
--- /dev/null
+++ b/test/functional/configs/stats.conf
@@ -0,0 +1,85 @@
+options = {
+ filters = ["spf", "dkim", "regexp"]
+ url_tld = "{= env.TESTDIR =}/../lua/unit/test_tld.dat"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid"
+ dns {
+ retransmits = 10;
+ timeout = 2s;
+ fake_records = [{
+ name = "example.net";
+ type = txt;
+ replies = ["v=spf1 -all"];
+ }]
+ }
+}
+logging = {
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log"
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+}
+
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ keypair {
+ pubkey = "{= env.KEY_PUB1 =}";
+ privkey = "{= env.KEY_PVT1 =}";
+ }
+ task_timeout = 60s;
+}
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ keypair {
+ pubkey = "{= env.KEY_PUB1 =}";
+ privkey = "{= env.KEY_PVT1 =}";
+ }
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl";
+}
+
+classifier {
+ languages_enabled = true;
+ tokenizer {
+ name = "osb";
+ hash = {= env.STATS_HASH =};
+ key = {= env.STATS_KEY =};
+ }
+ backend = "{= env.STATS_BACKEND =}";
+ statfile {
+ spam = true;
+ symbol = BAYES_SPAM;
+ size = 1M;
+ server = {= env.REDIS_SERVER =}
+ }
+ statfile {
+ spam = false;
+ symbol = BAYES_HAM;
+ size = 1M;
+ server = {= env.REDIS_SERVER =}
+ }
+
+ cache {
+ server = {= env.REDIS_SERVER =}
+ }
+
+ {% if env.STATS_PER_USER ~= '' %}
+ per_user = <<EOD
+return function(task)
+ return task:get_principal_recipient()
+end
+EOD;
+ {% endif %}
+}
+lua = "{= env.TESTDIR =}/lua/test_coverage.lua";
+
+settings {}
diff --git a/test/functional/configs/trivial.conf b/test/functional/configs/trivial.conf
new file mode 100644
index 0000000..97e3a30
--- /dev/null
+++ b/test/functional/configs/trivial.conf
@@ -0,0 +1,50 @@
+options = {
+ filters = ["spf", "dkim", "regexp"]
+ url_tld = "{= env.TESTDIR =}/../lua/unit/test_tld.dat"
+ pidfile = "{= env.TMPDIR =}/rspamd.pid";
+ lua_path = "{= env.INSTALLROOT =}/share/rspamd/lib/?.lua";
+ dns {
+ nameserver = ["8.8.8.8", "8.8.4.4"];
+ retransmits = 10;
+ timeout = 2s;
+ }
+}
+logging = {
+ log_urls = true;
+ type = "file",
+ level = "debug"
+ filename = "{= env.TMPDIR =}/rspamd.log";
+ log_usec = true;
+}
+metric = {
+ name = "default",
+ actions = {
+ reject = 100500,
+ }
+ unknown_weight = 1
+}
+
+worker {
+ type = normal
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"
+ count = 1
+ keypair {
+ pubkey = "{= env.KEY_PUB1 =}";
+ privkey = "{= env.KEY_PVT1 =}";
+ }
+ task_timeout = 10s;
+}
+
+worker {
+ type = controller
+ bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"
+ count = 1
+ secure_ip = ["127.0.0.1", "::1"];
+ stats_path = "{= env.TMPDIR =}/stats.ucl"
+}
+
+modules {
+ path = "{= env.TESTDIR =}/../../src/plugins/lua/"
+}
+lua = "{= env.INSTALLROOT =}/share/rspamd/rules/rspamd.lua"
+
diff --git a/test/functional/configs/url_redirector.conf b/test/functional/configs/url_redirector.conf
new file mode 100644
index 0000000..e6009ba
--- /dev/null
+++ b/test/functional/configs/url_redirector.conf
@@ -0,0 +1,8 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+redis {
+ servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}";
+}
+url_redirector {
+ redirector_hosts_map = "{= env.TESTDIR =}/configs/maps/redir.map";
+}
diff --git a/test/functional/configs/url_tags.conf b/test/functional/configs/url_tags.conf
new file mode 100644
index 0000000..9c82b84
--- /dev/null
+++ b/test/functional/configs/url_tags.conf
@@ -0,0 +1,9 @@
+url_tags {
+}
+redis {
+ servers = "${RSPAMD_REDIS_ADDR}:${RSPAMD_REDIS_PORT}";
+}
+
+options {
+ enable_experimental = true;
+}
diff --git a/test/functional/configs/whitelist.conf b/test/functional/configs/whitelist.conf
new file mode 100644
index 0000000..db264aa
--- /dev/null
+++ b/test/functional/configs/whitelist.conf
@@ -0,0 +1,83 @@
+.include(duplicate=append,priority=0) "{= env.TESTDIR =}/configs/plugins.conf"
+
+dmarc {}
+spf {}
+whitelist {
+
+ rules {
+
+ "WHITELIST_DDS" = {
+ valid_dkim = true;
+ valid_dmarc = true;
+ valid_spf = true;
+ domains = [
+ "{= env.TESTDIR =}/configs/maps/domains.list",
+ ];
+ score = -3.0;
+ inverse_symbol = "BLACKLIST_DDS";
+ }
+
+ "WHITELIST_DKIM" = {
+ valid_dkim = true;
+ domains = [
+ "{= env.TESTDIR =}/configs/maps/domains.list",
+ ];
+ description = "Mail comes from the whitelisted domain and has a valid DKIM signature";
+ score = -1.0;
+ inverse_symbol = "BLACKLIST_DKIM";
+ }
+
+ "WHITELIST_SPF" = {
+ valid_spf = true;
+ domains = [
+ "{= env.TESTDIR =}/configs/maps/domains.list",
+ ];
+ score = -1.0
+ inverse_multiplier = 3.0
+ description = "Mail comes from the whitelisted domain and has a valid SPF policy";
+ inverse_symbol = "BLACKLIST_SPF";
+ }
+
+ "WHITELIST_SPF_DKIM" = {
+ valid_spf = true;
+ valid_dkim = true;
+ domains = [
+ "{= env.TESTDIR =}/configs/maps/domains.list"
+ ];
+ score = -3.0;
+ description = "Mail comes from the whitelisted domain and has a valid SPF policy and valid DKIM signature";
+ }
+
+
+ "WHITELIST_DMARC_DKIM" = {
+ valid_dmarc = true;
+ valid_dkim = true;
+ domains = [
+ "{= env.TESTDIR =}/configs/maps/domains.list",
+ ];
+ score = -2.0;
+ description = "Mail comes from the whitelisted domain and has valid DMARC and DKIM policies";
+ inverse_symbol = "BLACKLIST_DMARC_DKIM";
+ }
+
+ "WHITELIST_DMARC" = {
+ valid_dmarc = true;
+ domains = [
+ "{= env.TESTDIR =}/configs/maps/domains.list",
+ ];
+ score = -2.0;
+ description = "Mail comes from the whitelisted domain and has valid DMARC policy";
+ inverse_symbol = "BLACKLIST_DMARC";
+ }
+
+ "STRICT_DMARC" = {
+ strict = true;
+ valid_dmarc = true;
+ domains = [
+ "{= env.TESTDIR =}/configs/maps/domains.list",
+ ];
+ score = -3.0;
+ }
+
+ }
+}