* SSH semi functional

This commit is contained in:
Bryan Ashby 2015-10-20 15:39:33 -06:00
parent 3833f9910e
commit 0f1fe31fe5
5 changed files with 53 additions and 46 deletions

View File

@ -184,7 +184,7 @@ function startListening() {
// :TODO: handle maxConnections, e.g. conf.maxConnections // :TODO: handle maxConnections, e.g. conf.maxConnections
server.on('client', function onClient(client) { server.on('client', function newClient(client, clientSock) {
// //
// Start tracking the client. We'll assign it an ID which is // Start tracking the client. We'll assign it an ID which is
// just the index in our connections array. // just the index in our connections array.
@ -193,7 +193,7 @@ function startListening() {
client.session = {}; client.session = {};
} }
clientConns.addNewClient(client); clientConns.addNewClient(client, clientSock);
client.on('ready', function onClientReady() { client.on('ready', function onClientReady() {

View File

@ -5,8 +5,9 @@
Portions of this code for key handling heavily inspired from the following: Portions of this code for key handling heavily inspired from the following:
https://github.com/chjj/blessed/blob/master/lib/keys.js https://github.com/chjj/blessed/blob/master/lib/keys.js
MIT license is as follows: chji's blessed is MIT licensed:
--------------------------
----/snip/----------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) <year> <copyright holders> Copyright (c) <year> <copyright holders>
@ -28,7 +29,7 @@
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
-------------------------- ----/snip/----------------------
*/ */
var term = require('./client_term.js'); var term = require('./client_term.js');
var miscUtil = require('./misc_util.js'); var miscUtil = require('./misc_util.js');
@ -86,9 +87,9 @@ function Client(input, output) {
var self = this; var self = this;
this.input = input; //this.input = input;
this.output = output; //this.output = output;
this.term = new term.ClientTerminal(this.output); //this.term = new term.ClientTerminal(this.output);
this.user = new user.User(); this.user = new user.User();
this.currentTheme = { info : { name : 'N/A', description : 'None' } }; this.currentTheme = { info : { name : 'N/A', description : 'None' } };
this.lastKeyPressMs = Date.now(); this.lastKeyPressMs = Date.now();
@ -110,6 +111,8 @@ function Client(input, output) {
} }
}); });
// //
// Peek at incoming |data| and emit events for any special // Peek at incoming |data| and emit events for any special
// handling that may include: // handling that may include:
@ -398,6 +401,13 @@ function Client(input, output) {
require('util').inherits(Client, stream); require('util').inherits(Client, stream);
Client.prototype.setInputOutput = function(input, output) {
this.input = input;
this.output = output;
this.term = new term.ClientTerminal(this.output);
};
Client.prototype.end = function () { Client.prototype.end = function () {
this.detachCurrentMenuModule(); this.detachCurrentMenuModule();

View File

@ -14,17 +14,17 @@ function getActiveConnections() {
return clientConnections.length; return clientConnections.length;
} }
function addNewClient(client) { function addNewClient(client, clientSock) {
var id = client.session.id = clientConnections.push(client) - 1; var id = client.session.id = clientConnections.push(client) - 1;
// Create a client specific logger // Create a client specific logger
client.log = logger.log.child( { clientId : id } ); client.log = logger.log.child( { clientId : id } );
var connInfo = { ip : client.input.remoteAddress }; var connInfo = { ip : clientSock.remoteAddress };
if(client.log.debug()) { if(client.log.debug()) {
connInfo.port = client.input.localPort; connInfo.port = clientSock.localPort;
connInfo.family = client.input.localFamily; connInfo.family = clientSock.localFamily;
} }
client.log.info(connInfo, 'Client connected'); client.log.info(connInfo, 'Client connected');

View File

@ -7,11 +7,7 @@ var baseClient = require('../client.js');
var Log = require('../logger.js').log; var Log = require('../logger.js').log;
var ServerModule = require('../server_module.js').ServerModule; var ServerModule = require('../server_module.js').ServerModule;
var userLogin = require('../user_login.js').userLogin; var userLogin = require('../user_login.js').userLogin;
var enigVersion = require('../../package.json').version;
// :TODO: remove this - currently an experimental hack:
var term = require('../client_term.js');
var packageJson = require('../../package.json');
var ssh2 = require('ssh2'); var ssh2 = require('ssh2');
var fs = require('fs'); var fs = require('fs');
@ -26,6 +22,26 @@ exports.moduleInfo = {
exports.getModule = SSHServerModule; exports.getModule = SSHServerModule;
/*
Hello,
If you follow the first server example in the `ssh2` readme and substitute the `session.once('exec', ...)` with `session.once('shell', ...)`
you should be fine. Just about all ssh clients default to an interactive shell session so that is what you will want to look for. As the
documentation notes, the `shell` event handler is just passed `accept, reject` with `accept()` returning a duplex stream representing
stdin/stdout. You can write to stderr by using the `stderr` property of the duplex stream object.
You will probably also want to handle the `pty` event on the session, since most clients (by default) will request a pseudo-TTY before
requesting an interactive shell. I believe this event may be especially useful in your case because the ssh client can send certain terminal
modes which can have relevance with your telnet usage. The event info also contains window dimensions which may help in determining layout
of your display (there is also a `window-change` event that contains these same dimensions whenever the client's screen/window dimensions
change).
If you are still having problems after making these changes, post your code somewhere and I will see if there is anything out of place.
Additionally, you can set `debug: console.log` in the server config object to show debug output which may be useful to see what is or isn't
being sent/received ssh protocol-wise.
*/
function SSHClient(clientConn) { function SSHClient(clientConn) {
baseClient.Client.apply(this, arguments); baseClient.Client.apply(this, arguments);
@ -106,7 +122,7 @@ function SSHClient(clientConn) {
var session = accept(); var session = accept();
session.on('pty-req', function pty(accept, reject, info) { session.on('pty', function pty(accept, reject, info) {
console.log(info); console.log(info);
var channel = accept(); var channel = accept();
console.log(channel) console.log(channel)
@ -116,13 +132,7 @@ function SSHClient(clientConn) {
session.on('shell', function shell(accept, reject) { session.on('shell', function shell(accept, reject) {
var channel = accept(); var channel = accept();
channel._write('Hello, world!') self.setInputOutput(channel.stdin, channel.stdout);
self.input = channel._client._sock;
self.output = channel._client._sock;
self.term = new term.ClientTerminal(self.output);
self.emit('ready') self.emit('ready')
}); });
@ -146,14 +156,13 @@ util.inherits(SSHServerModule, ServerModule);
SSHServerModule.prototype.createServer = function() { SSHServerModule.prototype.createServer = function() {
SSHServerModule.super_.prototype.createServer.call(this); SSHServerModule.super_.prototype.createServer.call(this);
// :TODO: setup all options here. What should the banner, etc. really be????
var serverConf = { var serverConf = {
privateKey : fs.readFileSync(conf.config.servers.ssh.rsaPrivateKey), privateKey : fs.readFileSync(conf.config.servers.ssh.rsaPrivateKey),
banner : 'ENiGMA½ BBS ' + packageJson.version + ' SSH Server', banner : 'ENiGMA½ BBS ' + enigVersion + ' SSH Server',
ident : 'enigma-bbs-' + packageJson.version + '-srv', ident : 'enigma-bbs-' + enigVersion + '-srv',
debug : function debugSsh(dbgLine) { debug : function debugSsh(dbgLine) {
if(true === conf.config.servers.ssh.debugConnections) { if(true === conf.config.servers.ssh.debugConnections) {
self.log.trace('SSH: ' + dbgLine); Log.trace('SSH: ' + dbgLine);
} }
}, },
}; };
@ -163,7 +172,8 @@ SSHServerModule.prototype.createServer = function() {
Log.info(info, 'New SSH connection'); Log.info(info, 'New SSH connection');
var client = new SSHClient(conn); var client = new SSHClient(conn);
this.emit('client', client);
this.emit('client', client, conn._sock);
}); });
return server; return server;

View File

@ -430,6 +430,8 @@ function TelnetClient(input, output) {
var readyFired = false; var readyFired = false;
var encodingSet = false; var encodingSet = false;
this.setInputOutput(input, output);
this.negotiationsComplete = false; // are we in the 'negotiation' phase? this.negotiationsComplete = false; // are we in the 'negotiation' phase?
this.didReady = false; // have we emit the 'ready' event? this.didReady = false; // have we emit the 'ready' event?
@ -761,21 +763,6 @@ Object.keys(OPTIONS).forEach(function(name) {
}); });
}); });
/*
function createServer() {
var server = net.createServer(function onConnection(sock) {
var self = this;
var client = new TelnetClient(sock, sock);
client.banner();
self.emit('client', client);
});
return server;
}
*/
function TelnetServerModule() { function TelnetServerModule() {
ServerModule.call(this); ServerModule.call(this);
} }
@ -791,7 +778,7 @@ TelnetServerModule.prototype.createServer = function() {
client.banner(); client.banner();
self.emit('client', client); self.emit('client', client, sock);
}); });
return server; return server;