haraka-plugin-limit
Advanced tools
Comparing version 1.0.2 to 1.0.4
## 1.0.4 - 2017-03-23 | ||
- for outbound, find domain at hmail.todo.domain then hmail.domain. | ||
- noop: use es6 arrow functions | ||
## 1.0.3 - 2017-03-09 | ||
- add `enabled=false` flag for each limit type, defaults to off, matching the docs. | ||
## 1.0.2 - 2017-02-06 | ||
@@ -3,0 +13,0 @@ |
119
index.js
@@ -15,3 +15,3 @@ 'use strict'; | ||
if (plugin.cfg.concurrency) { | ||
if (plugin.cfg.concurrency.enabled) { | ||
plugin.register_hook('connect_init', 'conn_concur_incr'); | ||
@@ -22,31 +22,31 @@ plugin.register_hook('connect', 'check_concurrency'); | ||
if (plugin.cfg.errors) { | ||
['helo','ehlo','mail','rcpt','data'].forEach(function (hook) { | ||
if (plugin.cfg.errors.enabled) { | ||
['helo','ehlo','mail','rcpt','data'].forEach(hook => { | ||
plugin.register_hook(hook, 'max_errors'); | ||
}); | ||
}) | ||
} | ||
if (plugin.cfg.recipients) { | ||
if (plugin.cfg.recipients.enabled) { | ||
plugin.register_hook('rcpt', 'max_recipients'); | ||
} | ||
if (plugin.cfg.unrecognized_commands) { | ||
if (plugin.cfg.unrecognized_commands.enabled) { | ||
plugin.register_hook('unrecognized_command', 'max_unrecognized_commands'); | ||
} | ||
if (plugin.cfg.rate_conn) { | ||
if (plugin.cfg.rate_conn.enabled) { | ||
plugin.register_hook('connect_init', 'rate_conn_incr'); | ||
plugin.register_hook('connect', 'rate_conn_enforce'); | ||
} | ||
if (plugin.cfg.rate_rcpt_host) { | ||
plugin.register_hook('connect', 'rate_rcpt_host_enforce'); | ||
plugin.register_hook('rcpt', 'rate_rcpt_host_incr'); | ||
if (plugin.cfg.rate_rcpt_host.enabled) { | ||
plugin.register_hook('connect', 'rate_rcpt_host_enforce'); | ||
plugin.register_hook('rcpt', 'rate_rcpt_host_incr'); | ||
} | ||
if (plugin.cfg.rate_rcpt_sender) { | ||
if (plugin.cfg.rate_rcpt_sender.enabled) { | ||
plugin.register_hook('rcpt', 'rate_rcpt_sender'); | ||
} | ||
if (plugin.cfg.rate_rcpt_null) { | ||
if (plugin.cfg.rate_rcpt_null.enabled) { | ||
plugin.register_hook('rcpt', 'rate_rcpt_null'); | ||
} | ||
if (plugin.cfg.rate_rcpt) { | ||
if (plugin.cfg.rate_rcpt.enabled) { | ||
plugin.register_hook('rcpt', 'rate_rcpt'); | ||
@@ -61,3 +61,3 @@ } | ||
} | ||
}; | ||
} | ||
@@ -68,3 +68,11 @@ exports.load_limit_ini = function () { | ||
booleans: [ | ||
'-outbound.enabled' | ||
'-outbound.enabled', | ||
'-recipients.enabled', | ||
'-unrecognized_commands.enabled', | ||
'-errors.enabled', | ||
'-rate_conn.enabled', | ||
'-rate_rcpt.enabled', | ||
'-rate_rcpt_host.enabled', | ||
'-rate_rcpt_sender.enabled', | ||
'-rate_rcpt_null.enabled', | ||
] | ||
@@ -188,3 +196,3 @@ }, | ||
plugin.db.incr(dbkey, function (err, count) { | ||
plugin.db.incr(dbkey, (err, count) => { | ||
if (err) { | ||
@@ -254,3 +262,3 @@ connection.results.add(plugin, { err: 'conn_concur_incr:' + err }); | ||
setTimeout(function () { | ||
setTimeout(() => { | ||
if (!connection) return; | ||
@@ -267,3 +275,3 @@ next(code, msg); | ||
var dbkey = plugin.get_concurrency_key(connection); | ||
plugin.db.incrby(dbkey, -1, function (err, concurrent) { | ||
plugin.db.incrby(dbkey, -1, (err, concurrent) => { | ||
if (err) connection.results.add(plugin, { err: 'conn_concur_decr:' + err }) | ||
@@ -325,3 +333,3 @@ return next(); | ||
// Default 0 = unlimited | ||
return cb(null, ip, 0); | ||
cb(null, ip, 0); | ||
}; | ||
@@ -357,3 +365,3 @@ | ||
// Default 0 = unlimited | ||
return cb(email, 0); | ||
cb(email, 0); | ||
}; | ||
@@ -418,3 +426,3 @@ | ||
plugin.db.incr(key, function (err, newval) { | ||
plugin.db.incr(key, (err, newval) => { | ||
if (err) return cb(err); | ||
@@ -424,4 +432,4 @@ | ||
cb(err, parseInt(newval, 10) > limit); // boolean true/false | ||
}); | ||
}; | ||
}) | ||
} | ||
@@ -432,12 +440,12 @@ exports.rate_rcpt_host_incr = function (next, connection) { | ||
plugin.get_host_key('rate_rcpt_host', connection, function (err, key, value) { | ||
plugin.get_host_key('rate_rcpt_host', connection, (err, key, value) => { | ||
if (!key || !value) return next(); | ||
key = 'rate_rcpt_host:' + key; | ||
plugin.db.incr(key, function (err2, newval) { | ||
plugin.db.incr(key, (err2, newval) => { | ||
if (newval === 1) plugin.db.expire(key, getTTL(value)); | ||
next(); | ||
}); | ||
}); | ||
}; | ||
}) | ||
}) | ||
} | ||
@@ -448,3 +456,3 @@ exports.rate_rcpt_host_enforce = function (next, connection) { | ||
plugin.get_host_key('rate_rcpt_host', connection, function (err, key, value) { | ||
plugin.get_host_key('rate_rcpt_host', connection, (err, key, value) => { | ||
if (err) { | ||
@@ -461,3 +469,3 @@ connection.results.add(plugin, { err: 'rate_rcpt_host:' + err }); | ||
plugin.db.get('rate_rcpt_host:' + key, function (err2, result) { | ||
plugin.db.get('rate_rcpt_host:' + key, (err2, result) => { | ||
if (err2) { | ||
@@ -485,7 +493,7 @@ connection.results.add(plugin, { err: 'rate_rcpt_host:' + err2 }); | ||
plugin.get_host_key('rate_conn', connection, function (err, key, value) { | ||
plugin.get_host_key('rate_conn', connection, (err, key, value) => { | ||
if (!key || !value) return next(); | ||
key = 'rate_conn:' + key; | ||
plugin.db.hincrby(key, + new Date(), 1, function (err2, newval) { | ||
plugin.db.hincrby(key, + new Date(), 1, (err2, newval) => { | ||
// extend key expiration on every new connection | ||
@@ -502,3 +510,3 @@ plugin.db.expire(key, getTTL(value) * 2); | ||
plugin.get_host_key('rate_conn', connection, function (err, key, value) { | ||
plugin.get_host_key('rate_conn', connection, (err, key, value) => { | ||
if (err) { | ||
@@ -517,3 +525,3 @@ connection.results.add(plugin, { err: 'rate_conn:' + err }); | ||
plugin.db.hgetall('rate_conn:' + key, function (err2, tstamps) { | ||
plugin.db.hgetall('rate_conn:' + key, (err2, tstamps) => { | ||
if (err2) { | ||
@@ -534,3 +542,3 @@ connection.results.add(plugin, { err: 'rate_conn:' + err }); | ||
var connections_in_ttl_period = 0; | ||
Object.keys(tstamps).forEach(function (ts) { | ||
Object.keys(tstamps).forEach(ts => { | ||
if (parseInt(ts, 10) < periodStartTs) return; // older than ttl | ||
@@ -553,5 +561,5 @@ connections_in_ttl_period = connections_in_ttl_period + parseInt(tstamps[ts], 10); | ||
plugin.get_mail_key('rate_rcpt_sender', connection.transaction.mail_from, function (key, value) { | ||
plugin.get_mail_key('rate_rcpt_sender', connection.transaction.mail_from, (key, value) => { | ||
plugin.rate_limit(connection, 'rate_rcpt_sender' + ':' + key, value, function (err, over) { | ||
plugin.rate_limit(connection, 'rate_rcpt_sender' + ':' + key, value, (err, over) => { | ||
if (err) { | ||
@@ -580,5 +588,5 @@ connection.results.add(plugin, { err: 'rate_rcpt_sender:' + err }); | ||
// Message from the null sender | ||
plugin.get_mail_key('rate_rcpt_null', params, function (key, value) { | ||
plugin.get_mail_key('rate_rcpt_null', params, (key, value) => { | ||
plugin.rate_limit(connection, 'rate_rcpt_null' + ':' + key, value, function (err2, over) { | ||
plugin.rate_limit(connection, 'rate_rcpt_null' + ':' + key, value, (err2, over) => { | ||
if (err2) { | ||
@@ -602,5 +610,5 @@ connection.results.add(plugin, { err: 'rate_rcpt_null:' + err2 }); | ||
if (Array.isArray(params)) params = params[0]; | ||
plugin.get_mail_key('rate_rcpt', params, function (key, value) { | ||
plugin.get_mail_key('rate_rcpt', params, (key, value) => { | ||
plugin.rate_limit(connection, 'rate_rcpt' + ':' + key, value, function (err2, over) { | ||
plugin.rate_limit(connection, 'rate_rcpt' + ':' + key, value, (err2, over) => { | ||
if (err2) { | ||
@@ -626,6 +634,14 @@ connection.results.add(plugin, { err: 'rate_rcpt:' + err2 }); | ||
function getOutKey (hmail) { | ||
return 'outbound-rate:' + hmail.domain; | ||
function getOutDom (hmail) { | ||
// outbound isn't internally consistent in the use of hmail.domain | ||
// vs hmail.todo.domain. | ||
// TODO: fix haraka/Haraka/outbound/HMailItem to be internally consistent. | ||
if (hmail.todo && hmail.todo.domain) return hmail.todo.domain; | ||
return hmail.domain; | ||
} | ||
function getOutKey (domain) { | ||
return 'outbound-rate:' + domain; | ||
} | ||
exports.outbound_increment = function (next, hmail) { | ||
@@ -635,3 +651,6 @@ var plugin = this; | ||
plugin.db.hincrby(getOutKey(hmail), 'TOTAL', 1, function (err, count) { | ||
var outDom = getOutDom(hmail); | ||
var outKey = getOutKey(outDom); | ||
plugin.db.hincrby(outKey, 'TOTAL', 1, (err, count) => { | ||
if (err) { | ||
@@ -642,6 +661,7 @@ plugin.logerror("outbound_increment: " + err); | ||
plugin.db.expire(getOutKey(hmail), 300); // 5 min expire | ||
if (!plugin.cfg.outbound[hmail.domain]) return next(); | ||
var limit = parseInt(plugin.cfg.outbound[hmail.domain], 10); | ||
plugin.db.expire(outKey, 300); // 5 min expire | ||
if (!plugin.cfg.outbound[outDom]) return next(); | ||
var limit = parseInt(plugin.cfg.outbound[outDom], 10); | ||
if (!limit) return next(); | ||
@@ -654,3 +674,3 @@ | ||
next(constants.delay, delay); | ||
}); | ||
}) | ||
} | ||
@@ -661,4 +681,5 @@ | ||
if (!plugin.db) return next(); | ||
plugin.db.hincrby(getOutKey(hmail), 'TOTAL', -1); | ||
plugin.db.hincrby(getOutKey(getOutDom(hmail)), 'TOTAL', -1); | ||
return next(); | ||
} |
{ | ||
"name": "haraka-plugin-limit", | ||
"version": "1.0.2", | ||
"version": "1.0.4", | ||
"description": "enforce various types of limits on remote MTAs", | ||
@@ -10,3 +10,3 @@ "main": "limit.js", | ||
"dependencies": { | ||
"haraka-constants": "^1.0.2", | ||
"haraka-constants": "*", | ||
"haraka-plugin-redis": "*", | ||
@@ -18,6 +18,6 @@ "ipaddr.js": "^1.2.0", | ||
"address-rfc2821": "*", | ||
"eslint": "^3.14.1", | ||
"eslint": "*", | ||
"eslint-plugin-haraka": "*", | ||
"haraka-test-fixtures": "*", | ||
"nodeunit": "^0.10.2" | ||
"nodeunit": "*" | ||
}, | ||
@@ -24,0 +24,0 @@ "scripts": { |
@@ -21,5 +21,3 @@ # limit | ||
Each limit type has values that can be defined in limit.ini. The default is empty / disabled until a value has been set. | ||
## Installation | ||
@@ -33,2 +31,11 @@ | ||
## Configure | ||
Each limit type has values that can be defined in limit.ini. See the default limit.ini in this packages config directory. | ||
Each limit type is disabled until `enabled=true` is set within it's block in limit.ini. | ||
Haraka's config loader loads the defaults from limit.ini within this plugins installed config directory and applies any overrides found in the limit.ini within your Haraka install/config directory. | ||
### [main] | ||
@@ -35,0 +42,0 @@ |
@@ -15,12 +15,12 @@ 'use strict'; | ||
outbound: { enabled: false }, | ||
recipients: { enabled: false }, | ||
unrecognized_commands: { enabled: false }, | ||
errors: { enabled: false }, | ||
rate_conn: { '127': 0, enabled: false, default: 5 }, | ||
rate_rcpt: { '127': 0, enabled: false, default: '50/5m' }, | ||
rate_rcpt_host: { '127': 0, enabled: false, default: '50/5m' }, | ||
rate_rcpt_sender: { '127': 0, enabled: false, default: '50/5m' }, | ||
rate_rcpt_null: { enabled: false, default: 1 }, | ||
redis: { db: 4, host: '127.0.0.1', port: '6379' }, | ||
concurrency: { plugin: 'karma', good: 10, bad: 1, none: 2 }, | ||
recipients: {}, | ||
unrecognized_commands: {}, | ||
errors: {}, | ||
rate_conn: { '127': 0, default: 5 }, | ||
rate_rcpt_host: { '127': 0, default: '50/5m' }, | ||
rate_rcpt_sender: { '127': 0, default: '50/5m' }, | ||
rate_rcpt: { '127': 0, default: '50/5m' }, | ||
rate_rcpt_null: { default: 1 } | ||
concurrency: { plugin: 'karma', good: 10, bad: 1, none: 2 } | ||
}; | ||
@@ -45,2 +45,2 @@ | ||
}; | ||
}; |
Sorry, the diff of this file is not supported yet
Floating dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
51371
969
254
0
2
Updatedharaka-constants@*