2015-03-17 04:41:14 +00:00
|
|
|
/* jslint node: true */
|
|
|
|
'use strict';
|
2014-10-17 02:21:06 +00:00
|
|
|
|
2015-03-17 04:41:14 +00:00
|
|
|
// ENiGMA½
|
2015-03-23 04:52:04 +00:00
|
|
|
var conf = require('../config.js');
|
|
|
|
var baseClient = require('../client.js');
|
2015-10-19 23:21:47 +00:00
|
|
|
var Log = require('../logger.js').log;
|
2015-03-23 04:52:04 +00:00
|
|
|
var ServerModule = require('../server_module.js').ServerModule;
|
2015-10-19 23:21:47 +00:00
|
|
|
var userLogin = require('../user_login.js').userLogin;
|
2014-10-17 02:21:06 +00:00
|
|
|
|
2015-10-20 04:33:11 +00:00
|
|
|
// :TODO: remove this - currently an experimental hack:
|
|
|
|
var term = require('../client_term.js');
|
|
|
|
|
|
|
|
var packageJson = require('../../package.json');
|
|
|
|
|
2015-03-17 04:41:14 +00:00
|
|
|
var ssh2 = require('ssh2');
|
|
|
|
var fs = require('fs');
|
2015-03-23 04:52:04 +00:00
|
|
|
var util = require('util');
|
2015-10-19 23:21:47 +00:00
|
|
|
var _ = require('lodash');
|
2014-10-17 02:21:06 +00:00
|
|
|
|
|
|
|
exports.moduleInfo = {
|
|
|
|
name : 'SSH',
|
|
|
|
desc : 'SSH Server',
|
2015-03-17 04:41:14 +00:00
|
|
|
author : 'NuSkooler'
|
2014-10-17 02:21:06 +00:00
|
|
|
};
|
|
|
|
|
2015-03-23 04:52:04 +00:00
|
|
|
exports.getModule = SSHServerModule;
|
2015-03-17 04:41:14 +00:00
|
|
|
|
2015-10-19 23:21:47 +00:00
|
|
|
function SSHClient(clientConn) {
|
2015-03-17 04:41:14 +00:00
|
|
|
baseClient.Client.apply(this, arguments);
|
|
|
|
|
2015-10-19 23:21:47 +00:00
|
|
|
//
|
|
|
|
// WARNING: Until we have emit 'ready', self.input, and self.output and
|
|
|
|
// not yet defined!
|
|
|
|
//
|
2015-03-17 04:41:14 +00:00
|
|
|
|
2015-10-19 23:21:47 +00:00
|
|
|
var self = this;
|
2015-03-17 04:41:14 +00:00
|
|
|
|
2015-10-19 23:21:47 +00:00
|
|
|
clientConn.on('authentication', function authentication(ctx) {
|
2015-10-20 04:33:11 +00:00
|
|
|
self.log.trace(
|
|
|
|
{
|
|
|
|
domain : ctx.domain,
|
|
|
|
username : ctx.username,
|
|
|
|
method : ctx.method,
|
|
|
|
}, 'SSH authentication');
|
2015-10-19 23:21:47 +00:00
|
|
|
|
|
|
|
// :TODO: check Config max failed logon attempts/etc.
|
|
|
|
|
|
|
|
switch(ctx.method) {
|
|
|
|
case 'password' :
|
|
|
|
// :TODO: Proper userLogin() here
|
|
|
|
self.user.authenticate(ctx.username, ctx.password, self, function authResult(err) {
|
|
|
|
if(err) {
|
|
|
|
ctx.reject();
|
|
|
|
} else {
|
|
|
|
ctx.accept();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'publickey' :
|
|
|
|
// :TODO:
|
|
|
|
ctx.reject();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'keyboard-interactive' :
|
|
|
|
if(!_.isString(ctx.username)) {
|
|
|
|
// :TODO: Let client know a username is required!
|
|
|
|
ctx.reject()
|
2015-03-17 04:41:14 +00:00
|
|
|
}
|
2015-10-19 23:21:47 +00:00
|
|
|
|
|
|
|
var PASS_PROMPT = { prompt : 'Password: ', echo : false };
|
|
|
|
|
|
|
|
ctx.prompt(PASS_PROMPT, function promptResponse(responses) {
|
|
|
|
if(0 === responses.length) {
|
|
|
|
return ctx.reject( ['keyboard-interactive'] );
|
|
|
|
}
|
|
|
|
|
|
|
|
userLogin(self, ctx.username, responses[0], function authResult(err) {
|
|
|
|
if(err) {
|
|
|
|
if(err.existingConn) {
|
|
|
|
// :TODO: Already logged in - how to let the SSH client know?
|
|
|
|
//self.term.write('User already logged in');
|
|
|
|
ctx.reject();
|
|
|
|
} else {
|
|
|
|
PASS_PROMPT.prompt = 'Invalid username or password\nPassword: ';
|
|
|
|
ctx.prompt(PASS_PROMPT, promptResponse);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ctx.accept();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
|
|
|
|
default :
|
2015-10-20 04:33:11 +00:00
|
|
|
self.log.info( { method : ctx.method }, 'Unsupported SSH authentication method');
|
2015-10-19 23:21:47 +00:00
|
|
|
ctx.reject();
|
2015-03-17 04:41:14 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-10-19 23:21:47 +00:00
|
|
|
clientConn.on('ready', function clientReady() {
|
|
|
|
self.log.info('SSH authentication success');
|
2015-03-19 05:08:23 +00:00
|
|
|
|
2015-10-19 23:21:47 +00:00
|
|
|
clientConn.on('session', function sess(accept, reject) {
|
2015-10-20 04:33:11 +00:00
|
|
|
|
|
|
|
var session = accept();
|
|
|
|
|
|
|
|
session.on('pty-req', function pty(accept, reject, info) {
|
|
|
|
console.log(info);
|
|
|
|
var channel = accept();
|
|
|
|
console.log(channel)
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
session.on('shell', function shell(accept, reject) {
|
|
|
|
var channel = accept();
|
|
|
|
|
|
|
|
channel._write('Hello, world!')
|
|
|
|
|
|
|
|
self.input = channel._client._sock;
|
|
|
|
self.output = channel._client._sock;
|
|
|
|
|
|
|
|
|
|
|
|
self.term = new term.ClientTerminal(self.output);
|
|
|
|
|
|
|
|
self.emit('ready')
|
|
|
|
});
|
|
|
|
|
2015-03-19 05:08:23 +00:00
|
|
|
});
|
2015-03-17 04:41:14 +00:00
|
|
|
});
|
|
|
|
|
2015-10-19 23:21:47 +00:00
|
|
|
clientConn.on('end', function clientEnd() {
|
2015-10-20 04:33:11 +00:00
|
|
|
//self.emit('end');
|
2015-03-17 04:41:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-03-23 04:52:04 +00:00
|
|
|
util.inherits(SSHClient, baseClient.Client);
|
|
|
|
|
|
|
|
function SSHServerModule() {
|
|
|
|
ServerModule.call(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
util.inherits(SSHServerModule, ServerModule);
|
|
|
|
|
|
|
|
SSHServerModule.prototype.createServer = function() {
|
|
|
|
SSHServerModule.super_.prototype.createServer.call(this);
|
2015-03-17 04:41:14 +00:00
|
|
|
|
|
|
|
// :TODO: setup all options here. What should the banner, etc. really be????
|
|
|
|
var serverConf = {
|
2015-10-19 23:21:47 +00:00
|
|
|
privateKey : fs.readFileSync(conf.config.servers.ssh.rsaPrivateKey),
|
2015-10-20 04:33:11 +00:00
|
|
|
banner : 'ENiGMA½ BBS ' + packageJson.version + ' SSH Server',
|
|
|
|
ident : 'enigma-bbs-' + packageJson.version + '-srv',
|
2015-10-19 23:21:47 +00:00
|
|
|
debug : function debugSsh(dbgLine) {
|
|
|
|
if(true === conf.config.servers.ssh.debugConnections) {
|
|
|
|
self.log.trace('SSH: ' + dbgLine);
|
|
|
|
}
|
2015-10-20 04:33:11 +00:00
|
|
|
},
|
2015-03-17 04:41:14 +00:00
|
|
|
};
|
2014-10-17 02:21:06 +00:00
|
|
|
|
2015-03-17 04:41:14 +00:00
|
|
|
var server = ssh2.Server(serverConf);
|
2015-03-19 05:08:23 +00:00
|
|
|
server.on('connection', function onConnection(conn, info) {
|
2015-10-19 23:21:47 +00:00
|
|
|
Log.info(info, 'New SSH connection');
|
|
|
|
|
|
|
|
var client = new SSHClient(conn);
|
2015-03-17 04:41:14 +00:00
|
|
|
this.emit('client', client);
|
2014-10-17 02:21:06 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
return server;
|
2015-03-23 04:52:04 +00:00
|
|
|
};
|