Merge branch 'master' of ssh://numinibsd/git/base/enigma-bbs
This commit is contained in:
commit
86bb8db0ef
|
@ -2,20 +2,21 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
var Config = require('../config.js').config;
|
const Config = require('../config.js').config;
|
||||||
var baseClient = require('../client.js');
|
const baseClient = require('../client.js');
|
||||||
var Log = require('../logger.js').log;
|
const Log = require('../logger.js').log;
|
||||||
var ServerModule = require('../server_module.js').ServerModule;
|
const ServerModule = require('../server_module.js').ServerModule;
|
||||||
var userLogin = require('../user_login.js').userLogin;
|
const userLogin = require('../user_login.js').userLogin;
|
||||||
var enigVersion = require('../../package.json').version;
|
const enigVersion = require('../../package.json').version;
|
||||||
var theme = require('../theme.js');
|
const theme = require('../theme.js');
|
||||||
const stringFormat = require('../string_format.js');
|
const stringFormat = require('../string_format.js');
|
||||||
|
|
||||||
var ssh2 = require('ssh2');
|
// deps
|
||||||
var fs = require('fs');
|
const ssh2 = require('ssh2');
|
||||||
var util = require('util');
|
const fs = require('fs');
|
||||||
var _ = require('lodash');
|
const util = require('util');
|
||||||
var assert = require('assert');
|
const _ = require('lodash');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
exports.moduleInfo = {
|
exports.moduleInfo = {
|
||||||
name : 'SSH',
|
name : 'SSH',
|
||||||
|
@ -34,18 +35,19 @@ function SSHClient(clientConn) {
|
||||||
// not yet defined!
|
// not yet defined!
|
||||||
//
|
//
|
||||||
|
|
||||||
var self = this;
|
const self = this;
|
||||||
|
|
||||||
var loginAttempts = 0;
|
let loginAttempts = 0;
|
||||||
|
|
||||||
clientConn.on('authentication', function authAttempt(ctx) {
|
clientConn.on('authentication', function authAttempt(ctx) {
|
||||||
var username = ctx.username || '';
|
const username = ctx.username || '';
|
||||||
var password = ctx.password || '';
|
const password = ctx.password || '';
|
||||||
|
|
||||||
self.isNewUser = (Config.users.newUserNames || []).indexOf(username) > -1;
|
self.isNewUser = (Config.users.newUserNames || []).indexOf(username) > -1;
|
||||||
|
|
||||||
self.log.trace( { method : ctx.method, username : username, newUser : self.isNewUser }, 'SSH authentication attempt');
|
self.log.trace( { method : ctx.method, username : username, newUser : self.isNewUser }, 'SSH authentication attempt');
|
||||||
|
|
||||||
function termConnection() {
|
function terminateConnection() {
|
||||||
ctx.reject();
|
ctx.reject();
|
||||||
clientConn.end();
|
clientConn.end();
|
||||||
}
|
}
|
||||||
|
@ -65,7 +67,7 @@ function SSHClient(clientConn) {
|
||||||
if(err) {
|
if(err) {
|
||||||
if(err.existingConn) {
|
if(err.existingConn) {
|
||||||
// :TODO: Can we display somthing here?
|
// :TODO: Can we display somthing here?
|
||||||
termConnection();
|
terminateConnection();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return ctx.reject(SSHClient.ValidAuthMethods);
|
return ctx.reject(SSHClient.ValidAuthMethods);
|
||||||
|
@ -84,28 +86,29 @@ function SSHClient(clientConn) {
|
||||||
return ctx.reject();
|
return ctx.reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
var interactivePrompt = { prompt: ctx.username + '\'s password: ', echo : false };
|
let interactivePrompt = { prompt : `${ctx.username}'s password: `, echo : false };
|
||||||
|
|
||||||
ctx.prompt(interactivePrompt, function retryPrompt(answers) {
|
ctx.prompt(interactivePrompt, function retryPrompt(answers) {
|
||||||
loginAttempts += 1;
|
loginAttempts += 1;
|
||||||
|
|
||||||
userLogin(self, username, (answers[0] || ''), function authResult(err) {
|
userLogin(self, username, (answers[0] || ''), err => {
|
||||||
if(err) {
|
if(err) {
|
||||||
if(err.existingConn) {
|
if(err.existingConn) {
|
||||||
// :TODO: can we display something here?
|
// :TODO: can we display something here?
|
||||||
termConnection();
|
terminateConnection();
|
||||||
} else {
|
} else {
|
||||||
if(loginAttempts >= Config.general.loginAttempts) {
|
if(loginAttempts >= Config.general.loginAttempts) {
|
||||||
termConnection();
|
terminateConnection();
|
||||||
} else {
|
} else {
|
||||||
var artOpts = {
|
const artOpts = {
|
||||||
client : self,
|
client : self,
|
||||||
name : 'SSHPMPT.ASC',
|
name : 'SSHPMPT.ASC',
|
||||||
readSauce : false,
|
readSauce : false,
|
||||||
};
|
};
|
||||||
theme.getThemeArt(artOpts, function gotArt(err, artInfo) {
|
|
||||||
|
theme.getThemeArt(artOpts, (err, artInfo) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
interactivePrompt.prompt = 'Access denied\n' + ctx.username + '\'s password: ';
|
interactivePrompt.prompt = `Access denied\n${ctx.username}'s password: `;
|
||||||
} else {
|
} else {
|
||||||
const newUserNameList = _.has(Config, 'users.newUserNames') && Config.users.newUserNames.length > 0 ?
|
const newUserNameList = _.has(Config, 'users.newUserNames') && Config.users.newUserNames.length > 0 ?
|
||||||
Config.users.newUserNames.map(newName => '"' + newName + '"').join(', ') :
|
Config.users.newUserNames.map(newName => '"' + newName + '"').join(', ') :
|
||||||
|
@ -130,8 +133,8 @@ function SSHClient(clientConn) {
|
||||||
// From ssh2 docs:
|
// From ssh2 docs:
|
||||||
// "rows and cols override width and height when rows and cols are non-zero."
|
// "rows and cols override width and height when rows and cols are non-zero."
|
||||||
//
|
//
|
||||||
var termHeight;
|
let termHeight;
|
||||||
var termWidth;
|
let termWidth;
|
||||||
|
|
||||||
if(info.rows > 0 && info.cols > 0) {
|
if(info.rows > 0 && info.cols > 0) {
|
||||||
termHeight = info.rows;
|
termHeight = info.rows;
|
||||||
|
@ -162,9 +165,9 @@ function SSHClient(clientConn) {
|
||||||
clientConn.once('ready', function clientReady() {
|
clientConn.once('ready', function clientReady() {
|
||||||
self.log.info('SSH authentication success');
|
self.log.info('SSH authentication success');
|
||||||
|
|
||||||
clientConn.on('session', function sess(accept, reject) {
|
clientConn.on('session', accept => {
|
||||||
|
|
||||||
var session = accept();
|
const session = accept();
|
||||||
|
|
||||||
session.on('pty', function pty(accept, reject, info) {
|
session.on('pty', function pty(accept, reject, info) {
|
||||||
self.log.debug(info, 'SSH pty event');
|
self.log.debug(info, 'SSH pty event');
|
||||||
|
@ -180,14 +183,14 @@ function SSHClient(clientConn) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
session.on('shell', function shell(accept, reject) {
|
session.on('shell', accept => {
|
||||||
self.log.debug('SSH shell event');
|
self.log.debug('SSH shell event');
|
||||||
|
|
||||||
var channel = accept();
|
const channel = accept();
|
||||||
|
|
||||||
self.setInputOutput(channel.stdin, channel.stdout);
|
self.setInputOutput(channel.stdin, channel.stdout);
|
||||||
|
|
||||||
channel.stdin.on('data', function clientData(data) {
|
channel.stdin.on('data', data => {
|
||||||
self.emit('data', data);
|
self.emit('data', data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -197,27 +200,25 @@ function SSHClient(clientConn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're ready!
|
// we're ready!
|
||||||
var firstMenu = self.isNewUser ? Config.servers.ssh.firstMenuNewUser : Config.servers.ssh.firstMenu;
|
const firstMenu = self.isNewUser ? Config.servers.ssh.firstMenuNewUser : Config.servers.ssh.firstMenu;
|
||||||
self.emit('ready', { firstMenu : firstMenu } );
|
self.emit('ready', { firstMenu : firstMenu } );
|
||||||
});
|
});
|
||||||
|
|
||||||
session.on('window-change', function windowChange(accept, reject, info) {
|
session.on('window-change', (accept, reject, info) => {
|
||||||
self.log.debug(info, 'SSH window-change event');
|
self.log.debug(info, 'SSH window-change event');
|
||||||
|
|
||||||
console.log('window-change: ' + accept)
|
|
||||||
|
|
||||||
self.updateTermInfo(info);
|
self.updateTermInfo(info);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
clientConn.on('end', function clientEnd() {
|
clientConn.on('end', () => {
|
||||||
self.emit('end'); // remove client connection/tracking
|
self.emit('end'); // remove client connection/tracking
|
||||||
});
|
});
|
||||||
|
|
||||||
clientConn.on('error', function connError(err) {
|
clientConn.on('error', err => {
|
||||||
self.log.warn( { error : err.toString(), code : err.code }, 'SSH connection error');
|
self.log.warn( { error : err.message, code : err.code }, 'SSH connection error');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,24 +235,28 @@ util.inherits(SSHServerModule, ServerModule);
|
||||||
SSHServerModule.prototype.createServer = function() {
|
SSHServerModule.prototype.createServer = function() {
|
||||||
SSHServerModule.super_.prototype.createServer.call(this);
|
SSHServerModule.super_.prototype.createServer.call(this);
|
||||||
|
|
||||||
var serverConf = {
|
const serverConf = {
|
||||||
privateKey : fs.readFileSync(Config.servers.ssh.privateKeyPem),
|
hostKeys : [
|
||||||
passphrase : Config.servers.ssh.privateKeyPass,
|
{
|
||||||
|
key : fs.readFileSync(Config.servers.ssh.privateKeyPem),
|
||||||
|
passphrase : Config.servers.ssh.privateKeyPass,
|
||||||
|
}
|
||||||
|
],
|
||||||
ident : 'enigma-bbs-' + enigVersion + '-srv',
|
ident : 'enigma-bbs-' + enigVersion + '-srv',
|
||||||
|
|
||||||
// Note that sending 'banner' breaks at least EtherTerm!
|
// Note that sending 'banner' breaks at least EtherTerm!
|
||||||
debug : function debugSsh(dbgLine) {
|
debug : (sshDebugLine) => {
|
||||||
if(true === Config.servers.ssh.traceConnections) {
|
if(true === Config.servers.ssh.traceConnections) {
|
||||||
Log.trace('SSH: ' + dbgLine);
|
Log.trace(`SSH: ${sshDebugLine}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var server = ssh2.Server(serverConf);
|
const server = ssh2.Server(serverConf);
|
||||||
server.on('connection', function onConnection(conn, info) {
|
server.on('connection', function onConnection(conn, info) {
|
||||||
Log.info(info, 'New SSH connection');
|
Log.info(info, 'New SSH connection');
|
||||||
|
|
||||||
var client = new SSHClient(conn);
|
const client = new SSHClient(conn);
|
||||||
|
|
||||||
this.emit('client', client, conn._sock);
|
this.emit('client', client, conn._sock);
|
||||||
});
|
});
|
||||||
|
|
10
package.json
10
package.json
|
@ -21,9 +21,12 @@
|
||||||
"binary": "0.3.x",
|
"binary": "0.3.x",
|
||||||
"buffers": "0.1.x",
|
"buffers": "0.1.x",
|
||||||
"bunyan": "^1.7.1",
|
"bunyan": "^1.7.1",
|
||||||
|
"farmhash": "^1.2.1",
|
||||||
|
"fs-extra": "0.26.x",
|
||||||
"gaze": "^0.5.2",
|
"gaze": "^0.5.2",
|
||||||
"hjson": "1.7.x",
|
"hjson": "1.7.x",
|
||||||
"iconv-lite": "^0.4.13",
|
"iconv-lite": "^0.4.13",
|
||||||
|
"inquirer": "^1.1.0",
|
||||||
"later": "1.2.0",
|
"later": "1.2.0",
|
||||||
"lodash": "^3.10.1",
|
"lodash": "^3.10.1",
|
||||||
"minimist": "1.2.x",
|
"minimist": "1.2.x",
|
||||||
|
@ -31,11 +34,8 @@
|
||||||
"node-uuid": "^1.4.7",
|
"node-uuid": "^1.4.7",
|
||||||
"ptyw.js": "NuSkooler/ptyw.js",
|
"ptyw.js": "NuSkooler/ptyw.js",
|
||||||
"sqlite3": "^3.1.1",
|
"sqlite3": "^3.1.1",
|
||||||
"ssh2": "^0.4.13",
|
"ssh2": "^0.5.1",
|
||||||
"temp": "^0.8.3",
|
"temp": "^0.8.3"
|
||||||
"inquirer" : "^1.1.0",
|
|
||||||
"fs-extra" : "0.26.x",
|
|
||||||
"farmhash" : "^1.2.1"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.2.0"
|
"node": ">=4.2.0"
|
||||||
|
|
Loading…
Reference in New Issue