Skip to content
Browse files

This adds more advanced RCPT TO blacklists and whitelists to haraka.

  • Loading branch information...
1 parent d0a9cba commit d67d183895588f9b20821208940d4e022ade00da @godsflaw godsflaw committed
View
1 config/rcpt_to.access.blacklist
@@ -0,0 +1 @@
+# addresses are matched exactly as written on each line.
View
5 config/rcpt_to.access.blacklist_regex
@@ -0,0 +1,5 @@
+# Does the same thing as the blacklist file, but each line is a regex.
+# Each line is also anchored for you, meaning '^' + regex + '$' is added for
+# you. If you need to get around this restriction, you may use a '.*' at
+# either the start or the end of your regex. This should help prevent people
+# from writing overly permissive rules on accident.
View
2 config/rcpt_to.access.ini
@@ -0,0 +1,2 @@
+[general]
+deny_msg=bad recipient address.
View
1 config/rcpt_to.access.whitelist
@@ -0,0 +1 @@
+# addresses are matched exactly as written on each line.
View
5 config/rcpt_to.access.whitelist_regex
@@ -0,0 +1,5 @@
+# Does the same thing as the whitelist file, but each line is a regex.
+# Each line is also anchored for you, meaning '^' + regex + '$' is added for
+# you. If you need to get around this restriction, you may use a '.*' at
+# either the start or the end of your regex. This should help prevent people
+# from writing overly permissive rules on accident.
View
54 docs/plugins/rcpt_to.access.md
@@ -0,0 +1,54 @@
+rcpt_to.access
+===================
+
+This plugin blocks RCPT_TO addresses in a list or regex.
+This plugin will evaluate the RCPT_TO address against a set of white and black
+lists. The lists are applied in the following way:
+
+rcpt_to.access.whitelist (pass)
+rcpt_to.access.whitelist_regex (pass)
+rcpt_to.access.blacklist (block)
+rcpt_to.access.blacklist_regex (block)
+
+Configuration rcpt_to.access.ini
+-------------------------------------
+
+General configuration file for this plugin.
+
+* rcpt_to.access.general.deny_msg
+
+ Text to send the user on reject (text).
+
+Configuration rcpt_to.access.whitelist
+-------------------------------------------
+
+The whitelist is mostly to counter blacklist entries that match more than
+what one would want. This file should be used for a specific address
+one per line, that should bypass blacklist checks.
+NOTE: We heavily suggest tailoring blacklist entries to be as accurate as
+possible and never using whitelists. Nevertheless, if you need whitelists,
+here they are.
+
+Configuration rcpt_to.access.whitelist_regex
+-------------------------------------------------
+
+Does the same thing as the whitelist file, but each line is a regex.
+Each line is also anchored for you, meaning '^' + regex + '$' is added for
+you. If you need to get around this restriction, you may use a '.*' at
+either the start or the end of your regex. This should help prevent people
+from writing overly permissive rules on accident.
+
+Configuration rcpt_to.access.blacklist
+-------------------------------------------
+
+This file should be used for a specific address, one per line, that should
+fail on connect.
+
+Configuration rcpt_to.access.blacklist_regex
+-------------------------------------------------
+
+Does the same thing as the blacklist file, but each line is a regex.
+Each line is also anchored for you, meaning '^' + regex + '$' is added for
+you. If you need to get around this restriction, you may use a '.*' at
+either the start or the end of your regex. This should help prevent people
+from writing overly permissive rules on accident.
View
6 docs/plugins/rcpt_to.blocklist.md
@@ -1,7 +1,11 @@
rcpt_to.blocklist
===================
-This mail blocks RCPT_TO addresses in a list.
+This plugin blocks RCPT_TO addresses in a list.
+
+NOTE: If all you need is to deny mail based on the exact address, this plugin
+will work just fine. If you want to customize the deny message, add blocks
+based on a regex, or add whitelists, please use the rcpt_to.access plugin.
Configuration
-------------
View
97 plugins/rcpt_to.access.js
@@ -0,0 +1,97 @@
+// rcpt_to.access plugin
+
+exports.register = function() {
+ var i;
+ var config = this.config.get('rcpt_to.access.ini');
+ this.wl = this.config.get('rcpt_to.access.whitelist', 'list');
+ this.bl = this.config.get('rcpt_to.access.blacklist', 'list');
+ this.deny_msg = config.general && (config.general['deny_msg'] ||
+ 'Connection rejected.');
+ var white_regex =
+ this.config.get('rcpt_to.access.whitelist_regex', 'list');
+ var black_regex =
+ this.config.get('rcpt_to.access.blacklist_regex', 'list');
+
+ if (white_regex.length) {
+ this.wlregex = new RegExp('^(?:' + white_regex.join('|') + ')$', 'i');
+ }
+
+ if (black_regex.length) {
+ this.blregex = new RegExp('^(?:' + black_regex.join('|') + ')$', 'i');
+ }
+
+ this.register_hook('rcpt_to', 'rcpt_to_access');
+}
+
+exports.rcpt_to_access = function(next, connection, params) {
+ var plugin = this;
+ var rcpt_to = params[0].address();
+
+ // address whitelist checks
+ if (rcpt_to) {
+ connection.logdebug(plugin, 'checking ' + rcpt_to +
+ ' against rcpt_to.access.whitelist');
+
+ if (_in_whitelist(connection, plugin, rcpt_to)) {
+ connection.logdebug(plugin, "Allowing " + rcpt_to);
+ return next();
+ }
+ }
+
+ // address blacklist checks
+ if (rcpt_to) {
+ connection.logdebug(plugin, 'checking ' + rcpt_to +
+ ' against rcpt_to.access.blacklist');
+
+ if (_in_blacklist(connection, plugin, rcpt_to)) {
+ connection.logdebug(plugin, "Rejecting, matched: " + rcpt_to);
+ return next(DENY, rcpt_to + plugin.deny_msg);
+ }
+ }
+
+ return next();
+}
+
+function _in_whitelist(connection, plugin, address) {
+ var i;
+ for (i in plugin.wl) {
+ connection.logdebug(plugin, 'checking ' + address + ' against ' + plugin.wl[i]);
+
+ if (plugin.wl[i] === address) {
+ return 1;
+ }
+ }
+
+ if (plugin.wlregex) {
+ connection.logdebug(plugin, 'checking ' + address + ' against ' +
+ plugin.wlregex.source);
+
+ if (address.match(plugin.wlregex)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+function _in_blacklist(connection, plugin, address) {
+ var i;
+ for (i in plugin.bl) {
+ connection.logdebug(plugin, 'checking ' + address + ' against ' + plugin.bl[i]);
+
+ if (plugin.bl[i] === address) {
+ return 1;
+ }
+ }
+
+ if (plugin.blregex) {
+ connection.logdebug(plugin, 'checking ' + address + ' against ' +
+ plugin.blregex.source);
+
+ if (address.match(plugin.blregex)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}

0 comments on commit d67d183

Please sign in to comment.
Something went wrong with that request. Please try again.