Merge branch 'master' of ssh://numinibsd/git/base/enigma-bbs

This commit is contained in:
Bryan Ashby 2016-09-11 16:22:26 -06:00
commit 86bb8db0ef
2 changed files with 57 additions and 52 deletions

View File

@ -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);
}); });

View File

@ -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"