haraka-net-utils
Advanced tools
Comparing version 1.1.5 to 1.2.0
### 1.2.0 - 2020-06-23 | ||
- added get_mx | ||
- remove deprecated load_tls_ini | ||
- remove deprecated tls_ini_section_with_defaults | ||
### 1.1.5 - 2020-04-11 | ||
@@ -3,0 +9,0 @@ |
125
index.js
'use strict'; | ||
// node.js built-ins | ||
const dns = require('dns'); | ||
const net = require('net'); | ||
const os = require('os'); | ||
const dns = require('dns'); | ||
const net = require('net'); | ||
const os = require('os'); | ||
const punycode = require('punycode') | ||
@@ -279,6 +280,6 @@ // npm modules | ||
exports.get_ipany_re = function (prefix, suffix, modifier) { | ||
/* jshint maxlen: false */ | ||
if (prefix === undefined) prefix = ''; | ||
if (suffix === undefined) suffix = ''; | ||
if (modifier === undefined) modifier = 'mg'; | ||
/* eslint-disable prefer-template */ | ||
return new RegExp( | ||
@@ -385,61 +386,83 @@ prefix + | ||
// deprecated, moved to Haraka/tls_socket, but | ||
// Haraka versions < 2.8.17 require this to be here. | ||
exports.load_tls_ini = function (cb) { | ||
exports.get_primary_host_name = function () { | ||
return exports.config.get('me') || os.hostname(); | ||
} | ||
const cfg = exports.config.get('tls.ini', { | ||
booleans: [ | ||
'-redis.disable_for_failed_hosts', | ||
exports.get_mx = function get_mx (raw_domain, cb) { | ||
let domain = raw_domain; | ||
const mxs = []; | ||
// wildcards match in any section and are not initialized | ||
'*.requestCert', | ||
'*.rejectUnauthorized', | ||
'*.honorCipherOrder', | ||
'*.enableOCSPStapling', | ||
'*.enableSNI', | ||
// Possible DNS errors | ||
// NODATA | ||
// FORMERR | ||
// BADRESP | ||
// NOTFOUND | ||
// BADNAME | ||
// TIMEOUT | ||
// CONNREFUSED | ||
// NOMEM | ||
// DESTRUCTION | ||
// NOTIMP | ||
// EREFUSED | ||
// SERVFAIL | ||
// explicitely declared booleans are initialized | ||
'+main.requestCert', | ||
'-main.rejectUnauthorized', | ||
'-main.honorCipherOrder', | ||
'-main.enableOCSPStapling', | ||
'-main.enableSNI', | ||
] | ||
}, cb); | ||
if ( /@/.test(domain) ) { | ||
domain = domain.split('@').pop(); | ||
// console.log(`\treduced ${raw_domain} to ${domain}.`) | ||
} | ||
if (!cfg.no_tls_hosts) cfg.no_tls_hosts = {}; | ||
if ( /^xn--/.test(domain) ) { | ||
// is punycode IDN with ACE, ASCII Compatible Encoding | ||
} | ||
else if (domain !== punycode.toASCII(domain)) { | ||
domain = punycode.toASCII(domain); | ||
console.log(`\tACE encoded '${raw_domain}' to '${domain}'`) | ||
} | ||
exports.tlsCfg = cfg; | ||
return cfg; | ||
} | ||
// wrap_mx returns our object with "priority" and "exchange" keys | ||
let wrap_mx = a => a; | ||
// deprecated, moved to Haraka/tls_socket, but | ||
// Haraka 2.8.16 requires this to be here. | ||
exports.tls_ini_section_with_defaults = function (section) { | ||
if (exports.tlsCfg === undefined) exports.load_tls_ini(); | ||
function process_dns (err, addresses) { | ||
if (err) { | ||
// Most likely this is a hostname with no MX record | ||
// Drop through and we'll get the A record instead. | ||
switch (err.code) { | ||
case 'ENODATA': | ||
case 'ENOTFOUND': | ||
return 0; | ||
default: | ||
} | ||
const inheritable_opts = [ | ||
'key', 'cert', 'ciphers', 'dhparam', | ||
'requestCert', 'honorCipherOrder', 'rejectUnauthorized' | ||
]; | ||
cb(err, mxs); | ||
} | ||
else if (addresses && addresses.length) { | ||
for (const addr of addresses) { | ||
mxs.push(wrap_mx(addr)); | ||
} | ||
if (exports.tlsCfg[section] === undefined) exports.tlsCfg[section] = {}; | ||
const cfg = JSON.parse(JSON.stringify(exports.tlsCfg[section])); | ||
for (const opt of inheritable_opts) { | ||
if (cfg[opt] === undefined) { | ||
// not declared in tls.ini[section] | ||
if (exports.tlsCfg.main[opt] !== undefined) { | ||
// use value from [main] section | ||
cfg[opt] = exports.tlsCfg.main[opt]; | ||
} | ||
cb(null, mxs); | ||
} | ||
else { | ||
// return zero if we need to keep trying next option | ||
return 0; | ||
} | ||
return 1; | ||
} | ||
return cfg; | ||
} | ||
dns.resolveMx(domain, (err, addresses) => { | ||
if (process_dns(err, addresses)) return; | ||
exports.get_primary_host_name = function () { | ||
return exports.config.get('me') || os.hostname(); | ||
// if MX lookup failed, we lookup an A record. To do that we change | ||
// wrap_mx() to return same thing as resolveMx() does. | ||
wrap_mx = a => ({ priority: 0, exchange: a }); | ||
// IS: IPv6 compatible | ||
dns.resolve(domain, (err2, addresses2) => { | ||
if (process_dns(err2, addresses2)) return; | ||
err2 = new Error("Found nowhere to deliver to"); | ||
err2.code = 'NOMX'; | ||
cb(err2, mxs); | ||
}) | ||
}) | ||
} |
{ | ||
"name": "haraka-net-utils", | ||
"version": "1.1.5", | ||
"version": "1.2.0", | ||
"description": "haraka network utilities", | ||
@@ -24,2 +24,5 @@ "main": "index.js", | ||
"license": "MIT", | ||
"engines": { | ||
"node": ">= v10.21.0" | ||
}, | ||
"bugs": { | ||
@@ -35,8 +38,9 @@ "url": "https://github.com/haraka/haraka-net-utils/issues" | ||
"dependencies": { | ||
"async": "^3.0.1", | ||
"async": "^3.2", | ||
"haraka-config": ">=1.0.11", | ||
"haraka-tld": "*", | ||
"ipaddr.js": "^1.2.0", | ||
"ipaddr.js": "^1.9.1", | ||
"punycode": "^2.1.1", | ||
"openssl-wrapper": "^0.3.4", | ||
"sprintf-js": "^1.0.3" | ||
"sprintf-js": "^1.1.2" | ||
}, | ||
@@ -43,0 +47,0 @@ "optionalDependencies": { |
@@ -14,3 +14,3 @@ ![CI Linux][ci-img] | ||
var net_utils = require('haraka-net-utils'); | ||
const net_utils = require('haraka-net-utils'); | ||
@@ -20,3 +20,3 @@ ### ip_to_long | ||
// Convert IPv4 to long | ||
var long = net_utils.ip_to_long('11.22.33.44'); // 185999660 | ||
const long = net_utils.ip_to_long('11.22.33.44'); // 185999660 | ||
@@ -26,3 +26,3 @@ ### long_to_ip | ||
// Convert long to IPv4 | ||
var ip = net_utils.long_to_ip(185999660); // 11.22.33.44 | ||
const ip = net_utils.long_to_ip(185999660); // 11.22.33.44 | ||
@@ -32,3 +32,3 @@ ### dec_to_hex | ||
// Convert decimal to hex | ||
var hex = net_utils.dec_to_hex(20111104); // 132df00 | ||
const hex = net_utils.dec_to_hex(20111104); // 132df00 | ||
@@ -38,3 +38,3 @@ ### hex_to_dec | ||
// Convert hex to decimal | ||
var dec = net_utils.hex_to_dec('132df00'); // 20111104 | ||
const dec = net_utils.hex_to_dec('132df00'); // 20111104 | ||
@@ -80,3 +80,12 @@ ### is_local_ipv4 | ||
### get_mx | ||
net_utils.get_mx(domain, (err, mxList) => { | ||
if (err) // handle any errors | ||
for (const mx of mxList) { | ||
// do something with each mx | ||
} | ||
}) | ||
[ci-img]: https://github.com/haraka/haraka-net-utils/workflows/CI%20Linux/badge.svg | ||
@@ -83,0 +92,0 @@ [ci-win-img]: https://github.com/haraka/haraka-net-utils/workflows/CI%20Windows/badge.svg |
@@ -1061,1 +1061,49 @@ | ||
}) | ||
describe('get_mx', function () { | ||
beforeEach(function (done) { | ||
this.net_utils = require('../index'); | ||
done(); | ||
}) | ||
it('gets MX records for a domain', function (done) { | ||
this.net_utils.get_mx('tnpi.net', (err, mxlist) => { | ||
assert.ifError(err); | ||
assert.ok(mxlist.length); | ||
assert.equal(mxlist[0].exchange, 'mail.theartfarm.com'); | ||
done(); | ||
}) | ||
}) | ||
it('gets MX records for an email address', function (done) { | ||
this.net_utils.get_mx('matt@tnpi.net', (err, mxlist) => { | ||
assert.ifError(err); | ||
assert.ok(mxlist.length); | ||
done(); | ||
}) | ||
}) | ||
it('gets MX records for example.com', function (done) { | ||
this.net_utils.get_mx('example.com', (err, mxlist) => { | ||
assert.equal(mxlist.length, 1); | ||
assert.equal(mxlist[0].exchange, ''); | ||
done(); | ||
}) | ||
}) | ||
it('gets an IP (no MX) for mail-toaster.org', function (done) { | ||
this.net_utils.get_mx('mail-toaster.org', (err, mxlist) => { | ||
assert.equal(mxlist.length, 1); | ||
assert.equal(mxlist[0].exchange, '66.128.51.170'); | ||
done(); | ||
}) | ||
}) | ||
it('gets a MX for über.cadillac.net', function (done) { | ||
this.net_utils.get_mx('über.cadillac.net', (err, mxlist) => { | ||
assert.equal(mxlist.length, 1); | ||
assert.equal(mxlist[0].exchange, '127.0.0.1'); | ||
done(); | ||
}) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79726
21
1398
93
8
+ Addedpunycode@^2.1.1
+ Addedpunycode@2.3.1(transitive)
Updatedasync@^3.2
Updatedipaddr.js@^1.9.1
Updatedsprintf-js@^1.1.2