Allow disabling logging for specific source IPs

This commit is contained in:
Andris Reinman 2017-10-12 16:01:27 +03:00
parent e87c33dc72
commit 69bc32db6e
9 changed files with 111 additions and 67 deletions

View file

@ -22,6 +22,9 @@ disableSTARTTLS=false
# If true, then expect HAProxy PROXY header as the first line of data
useProxy=false
# an array of IP addresses to ignore (not logged)
ignoredHosts=[]
[id]
#name="Wild Duck IMAP"
#version="1.0.0"

View file

@ -18,6 +18,9 @@ maxMessages=250
# If true, then expect HAProxy PROXY header as the first line of data
useProxy=false
# an array of IP addresses to ignore (not logged)
ignoredHosts=[]
[tls]
# If certificate path is not defined, use global or built-in self-signed certs
#key="/path/to/server/key.pem"

View file

@ -118,7 +118,7 @@ class IMAPCommand {
// Deny all literals bigger than maxMessage
command.expecting > maxAllowed
) {
this.connection._server.logger.debug(
this.connection.logger.debug(
{
tnx: 'client',
cid: this.connection.id
@ -170,7 +170,7 @@ class IMAPCommand {
this.append(command, err => {
if (err) {
this.connection._server.logger.debug(
this.connection.logger.debug(
{
err,
tnx: 'client',
@ -185,7 +185,7 @@ class IMAPCommand {
// check if the payload needs to be directed to a preset handler
if (typeof this.connection._nextHandler === 'function') {
this.connection._server.logger.debug(
this.connection.logger.debug(
{
tnx: 'client',
cid: this.connection.id
@ -203,7 +203,7 @@ class IMAPCommand {
errors.notifyConnection(this.connection, E, {
payload: this.payload ? (this.payload.length < 256 ? this.payload : this.payload.toString().substr(0, 150) + '...') : false
});
this.connection._server.logger.debug(
this.connection.logger.debug(
{
err: E,
tnx: 'client',
@ -227,7 +227,7 @@ class IMAPCommand {
});
}
this.connection._server.logger.debug(
this.connection.logger.debug(
{
tnx: 'client',
cid: this.connection.id

View file

@ -19,7 +19,7 @@ class IMAPComposer extends Transform {
if (typeof obj.pipe === 'function') {
// pipe stream to socket and wait until it finishes before continuing
this.connection._server.logger.debug(
this.connection.logger.debug(
{
tnx: 'pipeout',
cid: this.connection.id
@ -41,7 +41,7 @@ class IMAPComposer extends Transform {
let compiled = imapHandler.compiler(obj);
this.connection._server.logger.debug(
this.connection.logger.debug(
{
tnx: 'send',
cid: this.connection.id

View file

@ -26,10 +26,11 @@ class IMAPConnection extends EventEmitter {
super();
options = options || {};
// Random session ID, used for logging
this.id = options.id || crypto.randomBytes(9).toString('base64');
this.ignore = options.ignore;
this.compression = false;
this._deflate = false;
this._inflate = false;
@ -90,6 +91,15 @@ class IMAPConnection extends EventEmitter {
this._closing = false;
this._closed = false;
this.logger = {};
['info', 'debug', 'error'].forEach(level => {
this.logger[level] = (...args) => {
if (!this.ignore) {
this._server.logger[level](...args);
}
};
});
this._accountListener = message => {
if (message && message.action === 'LOGOUT') {
this.send('* BYE ' + (message.reason || 'Logout requested'));
@ -122,7 +132,7 @@ class IMAPConnection extends EventEmitter {
this._startSession();
this._server.logger.info(
this.logger.info(
{
tnx: 'connect',
cid: this.id
@ -149,7 +159,7 @@ class IMAPConnection extends EventEmitter {
// make sure we transmit the message immediatelly
this._deflate.flush();
}
this._server.logger.debug(
this.logger.debug(
{
tnx: 'send',
cid: this.id
@ -243,7 +253,7 @@ class IMAPConnection extends EventEmitter {
this._closed = true;
this._closing = false;
this._server.logger.info(
this.logger.info(
{
tnx: 'close',
cid: this.id
@ -290,7 +300,7 @@ class IMAPConnection extends EventEmitter {
errors.notifyConnection(this.this, err);
this._server.logger.error(
this.logger.error(
{
err,
cid: this.id
@ -308,7 +318,7 @@ class IMAPConnection extends EventEmitter {
* @event
*/
_onTimeout() {
this._server.logger.info(
this.logger.info(
{
tnx: 'connection',
cid: this.id
@ -444,7 +454,7 @@ class IMAPConnection extends EventEmitter {
listenerData.lock = false;
if (err) {
this._server.logger.info(
this.logger.info(
{
err,
tnx: 'updates',
@ -497,7 +507,7 @@ class IMAPConnection extends EventEmitter {
let existsResponse;
// show notifications
this._server.logger.debug(
this.logger.debug(
{
tnx: 'notifications',
cid: this.id
@ -553,7 +563,7 @@ class IMAPConnection extends EventEmitter {
this.selected.modifyIndex = update.modseq;
}
this._server.logger.debug(
this.logger.debug(
{
tnx: 'notifications',
cid: this.id
@ -567,7 +577,7 @@ class IMAPConnection extends EventEmitter {
continue; // skip this
}
this._server.logger.debug(
this.logger.debug(
{
tnx: 'notifications',
cid: this.id
@ -588,7 +598,7 @@ class IMAPConnection extends EventEmitter {
case 'EXPUNGE': {
let seq = (this.selected.uidList || []).indexOf(update.uid);
this._server.logger.debug(
this.logger.debug(
{
tnx: 'expunge',
cid: this.id

View file

@ -194,8 +194,13 @@ class IMAPServer extends EventEmitter {
}
_handleProxy(socket, callback) {
let socketOptions = {
id: crypto.randomBytes(9).toString('base64')
};
if (!this.options.useProxy) {
return setImmediate(callback);
socketOptions.ignore = this.options.ignoredHosts && this.options.ignoredHosts.includes(socket.remoteAddress);
return setImmediate(() => callback(null, socketOptions));
}
let chunks = [];
@ -214,10 +219,6 @@ class IMAPServer extends EventEmitter {
socket.unshift(remainder);
}
let socketOptions = {
id: crypto.randomBytes(9).toString('base64')
};
let header = Buffer.concat(chunks, chunklen)
.toString()
.trim();
@ -234,20 +235,25 @@ class IMAPServer extends EventEmitter {
}
if (params[1]) {
this.logger.info(
{
tnx: 'proxy',
cid: socketOptions.id,
proxy: params[1].trim().toLowerCase(),
destination: socket.remoteAddress
},
'[%s] PROXY from %s through %s (%s)',
socketOptions.id,
params[1].trim().toLowerCase(),
socket.remoteAddress,
JSON.stringify(params)
);
socketOptions.remoteAddress = params[1].trim().toLowerCase();
socketOptions.ignore = this.options.ignoredHosts && this.options.ignoredHosts.includes(socket.remoteAddress);
if (!socketOptions.ignore) {
this.logger.info(
{
tnx: 'proxy',
cid: socketOptions.id,
proxy: params[1].trim().toLowerCase()
},
'[%s] PROXY from %s through %s (%s)',
socketOptions.id,
params[1].trim().toLowerCase(),
params[2].trim().toLowerCase(),
JSON.stringify(params)
);
}
if (params[3]) {
socketOptions.remotePort = Number(params[3].trim()) || socketOptions.remotePort;
}

View file

@ -45,6 +45,7 @@ const serverOptions = {
ignoreSTARTTLS: config.imap.ignoreSTARTTLS,
useProxy: !!config.imap.useProxy,
ignoredHosts: config.imap.ignoredHosts,
id: {
name: config.imap.name || 'Wild Duck IMAP Server',

View file

@ -13,6 +13,8 @@ class POP3Connection extends EventEmitter {
options = options || {};
this.ignore = options.ignore;
this._server = server;
this._socket = socket;
@ -26,12 +28,21 @@ class POP3Connection extends EventEmitter {
this.processing = false;
this.queue = [];
this._remainder = '';
this.logger = {};
['info', 'debug', 'error'].forEach(level => {
this.logger[level] = (...args) => {
if (!this.ignore) {
this._server.logger[level](...args);
}
};
});
}
init() {
this._setListeners();
this._resetSession();
this._server.logger.info(
this.logger.info(
{
tnx: 'connection',
cid: this._id,
@ -59,7 +70,7 @@ class POP3Connection extends EventEmitter {
payload = payload.join('\r\n') + '\r\n.';
}
this._server.logger.debug(
this.logger.debug(
{
tnx: 'send',
cid: this._id,
@ -101,7 +112,7 @@ class POP3Connection extends EventEmitter {
this._closed = true;
this._closing = false;
this._server.logger.info(
this.logger.info(
{
tnx: 'close',
cid: this._id,
@ -127,7 +138,7 @@ class POP3Connection extends EventEmitter {
return;
}
this._server.logger.error(
this.logger.error(
{
err,
tnx: 'error',
@ -197,7 +208,7 @@ class POP3Connection extends EventEmitter {
if (typeof this._nextHandler === 'function') {
let handler = this._nextHandler;
this._nextHandler = null;
this._server.logger.debug(
this.logger.debug(
{
tnx: 'receive',
cid: this._id,
@ -208,7 +219,7 @@ class POP3Connection extends EventEmitter {
);
return handler(line, err => {
if (err) {
this._server.logger.info(
this.logger.info(
{
err,
tnx: '+',
@ -234,7 +245,7 @@ class POP3Connection extends EventEmitter {
if (/^(PASS|AUTH PLAIN)\s+[^\s]+/i.test(line)) {
logLine = logLine.replace(/[^\s]+$/, '*hidden*');
}
this._server.logger.debug(
this.logger.debug(
{
tnx: 'receive',
cid: this._id,
@ -247,7 +258,7 @@ class POP3Connection extends EventEmitter {
if (typeof this['command_' + command] === 'function') {
this['command_' + command](args, err => {
if (err) {
this._server.logger.info(
this.logger.info(
{
err,
tnx: 'command',
@ -329,7 +340,7 @@ class POP3Connection extends EventEmitter {
this.session,
(err, response) => {
if (err) {
this._server.logger.info(
this.logger.info(
{
err,
tnx: 'autherror',
@ -350,7 +361,7 @@ class POP3Connection extends EventEmitter {
}
if (!response || !response.user) {
this._server.logger.info(
this.logger.info(
{
tnx: 'authfail',
cid: this._id,
@ -365,7 +376,7 @@ class POP3Connection extends EventEmitter {
return next();
}
this._server.logger.info(
this.logger.info(
{
tnx: 'auth',
cid: this._id,
@ -781,7 +792,7 @@ class POP3Connection extends EventEmitter {
this.session,
(err, response) => {
if (err) {
this._server.logger.info(
this.logger.info(
{
err,
tnx: 'autherror',
@ -804,7 +815,7 @@ class POP3Connection extends EventEmitter {
}
if (!response.user) {
this._server.logger.info(
this.logger.info(
{
tnx: 'authfail',
cid: this._id,
@ -819,7 +830,7 @@ class POP3Connection extends EventEmitter {
return next();
}
this._server.logger.info(
this.logger.info(
{
tnx: 'auth',
cid: this._id,
@ -845,7 +856,7 @@ class POP3Connection extends EventEmitter {
openMailbox(next) {
this._server.onListMessages(this.session, (err, listing) => {
if (err) {
this._server.logger.info(
this.logger.info(
{
err,
tnx: 'listerr',

View file

@ -247,6 +247,15 @@ class POP3Server extends EventEmitter {
}
_handleProxy(socket, callback) {
let socketOptions = {
id: crypto.randomBytes(9).toString('base64')
};
if (!this.options.useProxy) {
socketOptions.ignore = this.options.ignoredHosts && this.options.ignoredHosts.includes(socket.remoteAddress);
return setImmediate(() => callback(null, socketOptions));
}
if (!this.options.useProxy) {
return setImmediate(callback);
}
@ -267,10 +276,6 @@ class POP3Server extends EventEmitter {
socket.unshift(remainder);
}
let socketOptions = {
id: crypto.randomBytes(9).toString('base64')
};
let header = Buffer.concat(chunks, chunklen)
.toString()
.trim();
@ -287,19 +292,24 @@ class POP3Server extends EventEmitter {
}
if (params[1]) {
this.logger.info(
{
tnx: 'proxy',
cid: socketOptions.id,
proxy: params[1].trim().toLowerCase(),
destination: socket.remoteAddress
},
'[%s] PROXY from %s through %s',
socketOptions.id,
params[1].trim().toLowerCase(),
socket.remoteAddress
);
socketOptions.remoteAddress = params[1].trim().toLowerCase();
socketOptions.ignore = this.options.ignoredHosts && this.options.ignoredHosts.includes(socket.remoteAddress);
if (!socketOptions.ignore) {
this.logger.info(
{
tnx: 'proxy',
cid: socketOptions.id,
proxy: params[1].trim().toLowerCase()
},
'[%s] PROXY from %s through %s',
socketOptions.id,
params[1].trim().toLowerCase(),
params[2].trim().toLowerCase()
);
}
if (params[3]) {
socketOptions.remotePort = Number(params[3].trim()) || socketOptions.remotePort;
}