* Disconnect clients that attempt to login with banned usernames for Telnet as well
* Slow disconnects to thwart brute force attacks - these names won't exist anyway, but we want the attacking client to not DoS us
This commit is contained in:
parent
06a1925288
commit
ee93035bb8
|
@ -25,6 +25,7 @@ This document attempts to track **major** changes and additions in ENiGMA½. For
|
|||
* NNTP support! See [NNTP docs](/docs/servers/nntp.md) for more information.
|
||||
* `oputil.js user rm` and `oputil.js user info` are in! See [oputil CLI](/docs/admin/oputil.md).
|
||||
* Performing a file scan/import using `oputil.js fb scan` now recognizes various `FILES.BBS` formats.
|
||||
* Usernames found in the `config.users.badUserNames` are now not only disallowed from applying, but disconnected at any login attempt.
|
||||
|
||||
|
||||
## 0.0.8-alpha
|
||||
|
|
|
@ -57,39 +57,46 @@ function SSHClient(clientConn) {
|
|||
}
|
||||
};
|
||||
|
||||
function terminateConnection() {
|
||||
const terminateConnection = () => {
|
||||
safeContextReject();
|
||||
return clientConn.end();
|
||||
}
|
||||
};
|
||||
|
||||
function promptAndTerm(msg) {
|
||||
// slow version to thwart brute force attacks
|
||||
const slowTerminateConnection = () => {
|
||||
setTimeout( () => {
|
||||
return terminateConnection();
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
const promptAndTerm = (msg, method = 'standard') => {
|
||||
if('keyboard-interactive' === ctx.method) {
|
||||
ctx.prompt(msg);
|
||||
}
|
||||
return terminateConnection();
|
||||
}
|
||||
return 'slow' === method ? slowTerminateConnection() : terminateConnection();
|
||||
};
|
||||
|
||||
function accountAlreadyLoggedIn(username) {
|
||||
const accountAlreadyLoggedIn = (username) => {
|
||||
return promptAndTerm(`${username} is already connected to the system. Terminating connection.\n(Press any key to continue)`);
|
||||
}
|
||||
};
|
||||
|
||||
function accountDisabled(username) {
|
||||
const accountDisabled = (username) => {
|
||||
return promptAndTerm(`${username} is disabled.\n(Press any key to continue)`);
|
||||
}
|
||||
};
|
||||
|
||||
function accountInactive(username) {
|
||||
const accountInactive = (username) => {
|
||||
return promptAndTerm(`${username} is waiting for +op activation.\n(Press any key to continue)`);
|
||||
}
|
||||
};
|
||||
|
||||
function accountLocked(username) {
|
||||
return promptAndTerm(`${username} is locked.\n(Press any key to continue)`);
|
||||
}
|
||||
const accountLocked = (username) => {
|
||||
return promptAndTerm(`${username} is locked.\n(Press any key to continue)`, 'slow');
|
||||
};
|
||||
|
||||
function isSpecialHandleError(err) {
|
||||
const isSpecialHandleError = (err) => {
|
||||
return [ ErrorReasons.AlreadyLoggedIn, ErrorReasons.Disabled, ErrorReasons.Inactive, ErrorReasons.Locked ].includes(err.reasonCode);
|
||||
}
|
||||
};
|
||||
|
||||
function handleSpecialError(err, username) {
|
||||
const handleSpecialError = (err, username) => {
|
||||
switch(err.reasonCode) {
|
||||
case ErrorReasons.AlreadyLoggedIn : return accountAlreadyLoggedIn(username);
|
||||
case ErrorReasons.Inactive : return accountInactive(username);
|
||||
|
@ -97,7 +104,7 @@ function SSHClient(clientConn) {
|
|||
case ErrorReasons.Locked : return accountLocked(username);
|
||||
default : return terminateConnection();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// If the system is open and |isNewUser| is true, the login
|
||||
|
@ -115,7 +122,7 @@ function SSHClient(clientConn) {
|
|||
}
|
||||
|
||||
if(Errors.BadLogin().code === err.code) {
|
||||
return terminateConnection();
|
||||
return slowTerminateConnection();
|
||||
}
|
||||
|
||||
return safeContextReject(SSHClient.ValidAuthMethods);
|
||||
|
@ -143,7 +150,7 @@ function SSHClient(clientConn) {
|
|||
}
|
||||
|
||||
if(Errors.BadLogin().code === err.code) {
|
||||
return terminateConnection();
|
||||
return slowTerminateConnection();
|
||||
}
|
||||
|
||||
const artOpts = {
|
||||
|
|
|
@ -34,6 +34,11 @@ function login(callingMenu, formData, extraArgs, cb) {
|
|||
return callingMenu.gotoMenu(callingMenu.menuConfig.config.tooNodeMenu, cb);
|
||||
}
|
||||
|
||||
// banned username results in disconnect
|
||||
if(ErrorReasons.NotAllowed === err.reasonCode) {
|
||||
return logoff(callingMenu, {}, {}, cb);
|
||||
}
|
||||
|
||||
const ReasonsMenus = [
|
||||
ErrorReasons.TooMany, ErrorReasons.Disabled, ErrorReasons.Inactive, ErrorReasons.Locked
|
||||
];
|
||||
|
|
|
@ -27,7 +27,11 @@ function userLogin(client, username, password, cb) {
|
|||
|
||||
if(config.users.badUserNames.includes(username.toLowerCase())) {
|
||||
client.log.info( { username : username }, 'Attempt to login with banned username');
|
||||
return cb(Errors.BadLogin(ErrorReasons.NotAllowed));
|
||||
|
||||
// slow down a bit to thwart brute force attacks
|
||||
return setTimeout( () => {
|
||||
return cb(Errors.BadLogin('Disallowed username', ErrorReasons.NotAllowed));
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
client.user.authenticate(username, password, err => {
|
||||
|
|
Loading…
Reference in New Issue