Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

helo.checks: make match_re work

1. precompile the regex list at load time (was: compile every regex on every connection)

2. test regexes, ignore and log error for bad ones

3. load .ini and regex list at register() with config parsing callback (was at connect())

4. added tests for match_re
  • Loading branch information...
commit 7f8d74282420d2ac6c36c23b8c1f822195e0cc20 1 parent 856db9b
@msimerson msimerson authored
Showing with 128 additions and 57 deletions.
  1. +68 −53 plugins/helo.checks.js
  2. +60 −4 tests/plugins/helo.checks.js
View
121 plugins/helo.checks.js
@@ -27,51 +27,54 @@ exports.register = function () {
plugin.register_hook('helo', hook);
plugin.register_hook('ehlo', hook);
}
-};
-exports.hook_connect = function (next, connection) {
- var plugin = this;
- plugin.cfg = plugin.config.get('helo.checks.ini', {
- booleans: [
- '+check.match_re',
- '+check.bare_ip',
- '+check.dynamic',
- '+check.big_company',
- '+check.valid_hostname',
- '+check.forward_dns',
- '+check.rdns_match',
- '+check.mismatch',
- '+check.proto_mismatch',
-
- '+reject.valid_hostname',
- '+reject.match_re',
- '+reject.bare_ip',
- '+reject.dynamic',
- '+reject.big_company',
- '-reject.forward_dns',
- '-reject.literal_mismatch',
- '-reject.rdns_match',
- '-reject.mismatch',
- '-reject.proto_mismatch',
-
- '+skip.private_ip',
- '+skip.whitelist',
- '+skip.relaying',
- ],
- });
-
- // backwards compatible with old config file
- if (plugin.cfg.check_no_dot !== undefined) {
- plugin.cfg.check.valid_hostname = plugin.cfg.check_no_dot ? true : false;
- }
- if (plugin.cfg.check_dynamic !== undefined) {
- plugin.cfg.check.dynamic = plugin.cfg.check_dynamic ? true : false;
- }
- if (plugin.cfg.check_raw_ip !== undefined) {
- plugin.cfg.check.bare_ip = plugin.cfg.check_raw_ip ? true : false;
- }
+ var load_config = function () {
+ plugin.cfg = plugin.config.get('helo.checks.ini', {
+ booleans: [
+ '+check.match_re',
+ '+check.bare_ip',
+ '+check.dynamic',
+ '+check.big_company',
+ '+check.valid_hostname',
+ '+check.forward_dns',
+ '+check.rdns_match',
+ '+check.mismatch',
+
+ '+reject.valid_hostname',
+ '+reject.match_re',
+ '+reject.bare_ip',
+ '+reject.dynamic',
+ '+reject.big_company',
+ '-reject.forward_dns',
+ '-reject.literal_mismatch',
+ '-reject.rdns_match',
+ '-reject.mismatch',
+
+ '+skip.private_ip',
+ '+skip.whitelist',
+ '+skip.relaying',
+ ],
+ }, load_config);
+
+ // backwards compatible with old config file
+ if (plugin.cfg.check_no_dot !== undefined) {
+ plugin.cfg.check.valid_hostname = plugin.cfg.check_no_dot ? true : false;
+ }
+ if (plugin.cfg.check_dynamic !== undefined) {
+ plugin.cfg.check.dynamic = plugin.cfg.check_dynamic ? true : false;
+ }
+ if (plugin.cfg.check_raw_ip !== undefined) {
+ plugin.cfg.check.bare_ip = plugin.cfg.check_raw_ip ? true : false;
+ }
+ };
+ load_config();
- return next();
+ var load_re_file = function () {
+ var regex_list = plugin.valid_regexes(plugin.config.get('helo.checks.regexps', 'list', load_re_file));
+ // pre-compile the regexes
+ plugin.cfg.list_re = new RegExp('^(' + regex_list.join('|') + ')$', 'i');
+ };
+ load_re_file();
};
exports.init = function (next, connection, helo) {
@@ -174,18 +177,14 @@ exports.match_re = function (next, connection, helo) {
if (plugin.should_skip(connection, 'match_re')) return next();
- var regexps = plugin.config.get('helo.checks.regexps', 'list');
-
- var fail=0;
- for (var i=0; i < regexps.length; i++) {
- var re = new RegExp('^' + regexps[i] + '$');
- if (re.test(helo)) {
- connection.results.add(plugin, {fail: 'match_re(' + regexps[i] + ')'});
- fail++;
+ if (plugin.cfg.list_re.test(helo)) {
+ connection.results.add(plugin, {fail: 'match_re'});
+ if (plugin.cfg.reject.match_re) {
+ return next(DENY, "That HELO not allowed here");
}
+ return next();
}
- if (fail && plugin.cfg.reject.match_re) return next(DENY, "BAD HELO");
- if (!fail) connection.results.add(plugin, {pass: 'match_re'});
+ connection.results.add(plugin, {pass: 'match_re'});
return next();
};
@@ -505,3 +504,19 @@ exports.get_a_records = function (host, cb) {
return cb(null, ips);
});
};
+
+exports.valid_regexes = function (list, file) {
+ // accepts an array of regexes and a file name
+ var valid = [];
+ for (var i=0; i<list.length; i++) {
+ try {
+ new RegExp(list[i]);
+ }
+ catch (e) {
+ this.logerror(this, "invalid regex in " + file + ", " + list[i]);
+ continue;
+ }
+ valid.push(list[i]);
+ }
+ return valid; // returns a list of valid regexes
+};
View
64 tests/plugins/helo.checks.js
@@ -20,10 +20,7 @@ function _set_up(callback) {
this.connection.results = new ResultStore(this.connection);
this.connection.remote_ip='208.75.199.19';
- this.plugin.hook_connect(stub, this.connection);
-
- // going to need these in multiple tests
- // this.plugin.register();
+ this.plugin.register();
callback();
}
@@ -615,3 +612,62 @@ exports.forward_dns = {
this.plugin.forward_dns(cb, this.connection, test_helo);
},
};
+
+exports.match_re = {
+ setUp : _set_up,
+ tearDown : _tear_down,
+ 'miss' : function (test) {
+ test.expect(3);
+ var test_helo = 'not_in_re_list.net';
+ var cb = function (rc, msg) {
+ test.equal(undefined, rc);
+ test.equal(undefined, msg);
+ test.ok(this.connection.results.get('helo.checks').pass.length);
+ test.done();
+ }.bind(this);
+ this.plugin.init(stub, this.connection, test_helo);
+ this.plugin.cfg.list_re = new RegExp('^(' + ['bad.tld'].join('|') + ')$', 'i');
+ this.plugin.match_re(cb, this.connection, test_helo);
+ },
+ 'hit, reject=no' : function (test) {
+ test.expect(3);
+ var test_helo = 'ylmf-pc';
+ var cb = function (rc, msg) {
+ test.equal(undefined, rc);
+ test.equal(undefined, msg);
+ test.ok(this.connection.results.get('helo.checks').fail.length);
+ test.done();
+ }.bind(this);
+ this.plugin.init(stub, this.connection, test_helo);
+ this.plugin.cfg.list_re = new RegExp('^(' + ['ylmf-pc'].join('|') + ')$', 'i');
+ this.plugin.match_re(cb, this.connection, test_helo);
+ },
+ 'hit, reject=yes, exact' : function (test) {
+ test.expect(3);
+ var test_helo = 'ylmf-pc';
+ var cb = function (rc, msg) {
+ test.equal(DENY, rc);
+ test.equal('That HELO not allowed here', msg);
+ test.ok(this.connection.results.get('helo.checks').fail.length);
+ test.done();
+ }.bind(this);
+ this.plugin.init(stub, this.connection, test_helo);
+ this.plugin.cfg.reject = { match_re: true };
+ this.plugin.cfg.list_re = new RegExp('^(' + ['ylmf-pc'].join('|') + ')$', 'i');
+ this.plugin.match_re(cb, this.connection, test_helo);
+ },
+ 'hit, reject=yes, pattern' : function (test) {
+ test.expect(3);
+ var test_helo = 'ylmf-pc';
+ var cb = function (rc, msg) {
+ test.equal(DENY, rc);
+ test.equal('That HELO not allowed here', msg);
+ test.ok(this.connection.results.get('helo.checks').fail.length);
+ test.done();
+ }.bind(this);
+ this.plugin.init(stub, this.connection, test_helo);
+ this.plugin.cfg.reject = { match_re: true };
+ this.plugin.cfg.list_re = new RegExp('^(' + ['ylm.*'].join('|') + ')$', 'i');
+ this.plugin.match_re(cb, this.connection, test_helo);
+ },
+};
Please sign in to comment.
Something went wrong with that request. Please try again.