Skip to content

Commit

Permalink
Release v1.1.0 (#14)
Browse files Browse the repository at this point in the history
- dep(ldapjs): update 1.0.2 -> 2.3.3
- style: use es6 arrow functions
- style: inline uses of `plugin`
  • Loading branch information
msimerson committed Apr 28, 2023
1 parent c818fc5 commit 510d0f0
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: CI

on: [ push ]
on: [ push, pull_request ]

env:
CI: true
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ on:
push:
branches:
- master
paths:
- package.json

env:
CI: true
Expand Down
2 changes: 1 addition & 1 deletion .release
Submodule .release updated 4 files
+6 −2 CHANGELOG.md
+8 −0 README.md
+4 −1 finish.sh
+2 −2 submit.sh
12 changes: 12 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
### Unreleased


### [1.1.0] - 2023-04-28

#### Changed

- dep(ldapjs): update 1.0.2 -> 2.3.3
- style: use es6 arrow functions
- style: inline uses of `plugin`


### 1.0.1 - 2022-06-05

- ci: add GHA ci workflow
Expand All @@ -11,3 +20,6 @@
### 1.0.0 - 2017-09-__

- initial release


[1.1.0]: https://github.com/haraka/haraka-plugin-rcpt-ldap/releases/tag/1.1.0
80 changes: 38 additions & 42 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,99 +3,96 @@
const util = require('util');

exports.register = function () {
const plugin = this;
plugin.inherits('rcpt_to.host_list_base');
this.inherits('rcpt_to.host_list_base');

try {
plugin.ldap = require('ldapjs');
this.ldap = require('ldapjs');
}
catch (e) {
plugin.logerror("failed to load ldapjs, " +
this.logerror("failed to load ldapjs, " +
" try installing it: npm install ldapjs");
return;
}

// only load this stuff if ldapjs loaded
plugin.load_host_list();
plugin.load_ldap_ini();
plugin.register_hook('rcpt', 'ldap_rcpt');
};
this.load_host_list();
this.load_ldap_ini();
this.register_hook('rcpt', 'ldap_rcpt');
}

exports.load_ldap_ini = function () {
const plugin = this;
plugin.cfg = plugin.config.get('rcpt_to.ldap.ini', 'ini', function () {
plugin.load_ldap_ini();
this.cfg = this.config.get('rcpt_to.ldap.ini', 'ini', () => {
this.load_ldap_ini();
});
};
}

exports.ldap_rcpt = function (next, connection, params) {
const plugin = this;
const txn = connection.transaction;
if (!txn) return next();

const rcpt = txn.rcpt_to[txn.rcpt_to.length - 1];
if (!rcpt.host) {
txn.results.add(plugin, {fail: '!domain'});
txn.results.add(this, {fail: '!domain'});
return next();
}
const domain = rcpt.host.toLowerCase();

if (!plugin.in_host_list(domain) && !plugin.in_ldap_ini(domain)) {
connection.logdebug(plugin, `domain '${ domain }' is not local; skip ldap`);
if (!this.in_host_list(domain) && !this.in_ldap_ini(domain)) {
connection.logdebug(this, `domain '${ domain }' is not local; skip ldap`);
return next();
}

const ar = txn.results.get('access');
if (ar && ar.pass.length > 0 && ar.pass.indexOf("rcpt_to.access.whitelist") !== -1) {
connection.loginfo(plugin, "skip whitelisted recipient");
if (ar && ar.pass.length > 0 && ar.pass.includes("rcpt_to.access.whitelist")) {
connection.loginfo(this, "skip whitelisted recipient");
return next();
}

txn.results.add(plugin, { msg: 'connecting' });
txn.results.add(this, { msg: 'connecting' });

const cfg = plugin.cfg[domain] || plugin.cfg.main;
const cfg = this.cfg[domain] || this.cfg.main;
if (!cfg) {
connection.logerror(plugin, `no LDAP config for ${ domain}`);
connection.logerror(this, `no LDAP config for ${ domain}`);
return next();
}

let client;
try { client = plugin.ldap.createClient({ url: cfg.server }); }
try { client = this.ldap.createClient({ url: cfg.server }); }
catch (e) {
connection.logerror(plugin, `connect error: ${ e}`);
connection.logerror(this, `connect error: ${ e}`);
return next();
}

client.on('error', function (err) {
connection.loginfo(plugin, `client error ${ err.message}`);
client.on('error', (err) => {
connection.loginfo(this, `client error ${ err.message}`);
next(DENYSOFT, 'Backend failure. Please, retry later');
});

client.bind(cfg.binddn, cfg.bindpw, function (err) {
connection.logerror(plugin, `error: ${ err}`);
client.bind(cfg.binddn, cfg.bindpw, (err) => {
connection.logerror(this, `error: ${ err}`);
});

const opts = plugin.get_search_opts(cfg, rcpt);
connection.logdebug(plugin, `Search filter is: ${ util.inspect(opts)}`);
const opts = this.get_search_opts(cfg, rcpt);
connection.logdebug(this, `Search filter is: ${ util.inspect(opts)}`);

const search_result = function (err, res) {
const search_result = (err, res) => {
if (err) {
connection.logerror(plugin, `LDAP search error: ${ err}`);
connection.logerror(this, `LDAP search error: ${ err}`);
return next(DENYSOFT, 'Backend failure. Please, retry later');
}
const items = [];
res.on('searchEntry', function (entry) {
connection.logdebug(plugin, `entry: ${ JSON.stringify(entry.object)}`);
res.on('searchEntry', (entry) => {
connection.logdebug(this, `entry: ${ JSON.stringify(entry.object)}`);
items.push(entry.object);
});

res.on('error', function (err2) { // called for tcp (non-ldap) errors
connection.logerror(plugin, `LDAP search error: ${ err2}`);
res.on('error', (err2) => { // called for tcp (non-ldap) errors
connection.logerror(this, `LDAP search error: ${ err2}`);
next(DENYSOFT, 'Backend failure. Please, retry later');
});

res.on('end', function (result) {
connection.logdebug(plugin, `LDAP search results: ${ items.length } -- ${ util.inspect(items)}`);
res.on('end', (result) => {
connection.logdebug(this, `LDAP search results: ${ items.length } -- ${ util.inspect(items)}`);

if (items.length) return next();

Expand All @@ -105,7 +102,7 @@ exports.ldap_rcpt = function (next, connection, params) {
client.search(cfg.basedn, opts, search_result);
};

exports.get_search_opts = function (cfg, rcpt) {
exports.get_search_opts = (cfg, rcpt) => {

const plain_rcpt = rcpt.address().toLowerCase();
// JSON.stringify(rcpt.original).replace(/</, '').replace(/>/, '').replace(/"/g, '');
Expand All @@ -118,10 +115,9 @@ exports.get_search_opts = function (cfg, rcpt) {
};

exports.in_ldap_ini = function (domain) {
const plugin = this;
if (!domain) return false;
if (!plugin.cfg) return false;
if (!plugin.cfg[domain]) return false;
if (!plugin.cfg[domain].server) return false;
if (!this.cfg) return false;
if (!this.cfg[domain]) return false;
if (!this.cfg[domain].server) return false;
return true;
};
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "haraka-plugin-rcpt-ldap",
"version": "1.0.1",
"version": "1.1.0",
"description": "Haraka plugin that validates recipients against an LDAP server",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -30,6 +30,6 @@
"mocha": ">=9"
},
"dependencies": {
"ldapjs": "^1.0.2"
"ldapjs": "^2.3.3"
}
}

0 comments on commit 510d0f0

Please sign in to comment.