diff --git a/index.js b/index.js index 3dde600..3adea28 100644 --- a/index.js +++ b/index.js @@ -12,10 +12,12 @@ var io = require('socket.io')(server); var path = require('path'); var basicAuth = require('basic-auth'); -var ssh = require('ssh2'); +var ssh = require('ssh2').Client; var readConfig = require('read-config'), config = readConfig(__dirname + '/config.json'); var myError = " - "; +var termCols; +var termRows; function logErrors(err, req, res, next) { console.error(err.stack); @@ -64,6 +66,10 @@ app.use(express.static(__dirname + '/public')).use(function(req, res, next) { io.on('connection', function(socket) { var conn = new ssh(); + socket.on('geometry', function (cols, rows) { + termCols = cols; + termRows = rows; + }); conn.on('banner', function(d) { //need to convert to cr/lf for proper formatting d = d.replace(/\r?\n/g, "\r\n"); @@ -76,7 +82,8 @@ io.on('connection', function(socket) { socket.emit('status', 'SSH CONNECTION ESTABLISHED'); socket.emit('statusBackground', 'green'); socket.emit('allowreplay', config.options.allowreplay); - conn.shell( { term: config.ssh.term }, function(err, stream) { + + conn.shell( { term: config.ssh.term, cols: termCols, rows: termRows }, function(err, stream) { if (err) { console.log (err.message); myError = myError + err.message; @@ -99,6 +106,7 @@ io.on('connection', function(socket) { }).on('close', function(code, signal) { console.log('Stream :: close :: code: ' + code + ', signal: ' + signal); conn.end(); + socket.disconnect(); }).stderr.on('data', function(data) { console.log('STDERR: ' + data); }); @@ -106,9 +114,11 @@ io.on('connection', function(socket) { }).on('end', function() { socket.emit('status', 'SSH CONNECTION CLOSED BY HOST' + myError); socket.emit('statusBackground', 'red'); + socket.disconnect(); }).on('close', function() { socket.emit('status', 'SSH CONNECTION CLOSE' + myError); socket.emit('statusBackground', 'red'); + socket.disconnect(); }).on('error', function(err) { myError = myError + err; socket.emit('status', 'SSH CONNECTION ERROR' + myError); diff --git a/public/client.htm b/public/client.htm index 69ddb97..bbd4b84 100644 --- a/public/client.htm +++ b/public/client.htm @@ -15,7 +15,9 @@
-
CREDENTIALS
+
CREDENTIALS
+
Download Log
+
Start Log
diff --git a/public/client.js b/public/client.js index 8caa795..c042850 100644 --- a/public/client.js +++ b/public/client.js @@ -1,13 +1,17 @@ +var sessionLog, + sessionLogEnable = false, + sessionFooter, + logDate; +document.getElementById('downloadLog').style.display = 'none'; var terminalContainer = document.getElementById('terminal-container'), term = new Terminal({ - cursorBlink: true + cursorBlink: true }), socket, termid; term.open(terminalContainer); term.fit(); -var cols = term.cols, - rows = term.rows; + if (document.location.pathname) { var parts = document.location.pathname.split('/'), base = parts.slice(0, parts.length - 1).join('/') + '/', @@ -18,22 +22,52 @@ if (document.location.pathname) { } else { socket = io.connect(); } -var credentialReplay = document.getElementById('credentials') -credentialReplay.onclick = replayCredentials; function replayCredentials() { socket.emit('control', 'replayCredentials'); - //term.writeln('sending credentials'); - return true; + console.log("replaying credentials"); + return false; +} + +function startLog() { + if (sessionLogEnable == true) { + sessionLogEnable = false; + document.getElementById('startLog').innerHTML = 'Start Log'; + console.log("stopping log, " + sessionLogEnable); + currentDate = new Date(); + sessionLog = sessionLog + "\r\n\r\nLog End for " + sessionFooter + ": " + currentDate.getFullYear() + "/" + (currentDate.getMonth() + 1) + "/" + currentDate.getDate() + " @ " + currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds() + "\r\n"; + logDate = currentDate; + return false; + } else { + sessionLogEnable = true; + document.getElementById('startLog').innerHTML = 'Logging - STOP LOG'; + document.getElementById('downloadLog').style.display = 'inline'; + console.log("starting log, " + sessionLogEnable); + currentDate = new Date(); + sessionLog = "Log Start for " + sessionFooter + ": " + currentDate.getFullYear() + "/" + (currentDate.getMonth() + 1) + "/" + currentDate.getDate() + " @ " + currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds() + "\r\n\r\n"; + logDate = currentDate; + return false; + } +} + +function downloadLog() { + myFile = "WebSSH2-" + logDate.getFullYear() + (logDate.getMonth() + 1) + logDate.getDate() + "_" + logDate.getHours() + logDate.getMinutes() + logDate.getSeconds() + ".log"; + var blob = new Blob([sessionLog], { + type: 'text/plain' + }); + if (window.navigator.msSaveOrOpenBlob) { + window.navigator.msSaveBlob(blob, myFile); + } else { + var elem = window.document.createElement('a'); + elem.href = window.URL.createObjectURL(blob); + elem.download = myFile; + document.body.appendChild(elem); + elem.click(); + document.body.removeChild(elem); + } } -socket.emit('create', term.cols, term.rows, function(err, data) { - if (err) return self._destroy(); - self.pty = data.pty; - self.id = data.id; - termid = self.id; - term.emit('open tab', self); -}); socket.on('connect', function() { + socket.emit('geometry', term.cols, term.rows); term.on('data', function(data) { socket.emit('data', data); }); @@ -46,26 +80,28 @@ socket.on('connect', function() { }).on('header', function(data) { document.getElementById('header').innerHTML = data; }).on('footer', function(data) { + sessionFooter = data; document.getElementById('footer').innerHTML = data; }).on('statusBackground', function(data) { document.getElementById('status').style.backgroundColor = data; }).on('allowreplay', function(data) { - console.log ('allowreplay: ' + data); if (data == 'true') { + console.log('allowreplay: ' + data); document.getElementById('credentials').style.display = 'inline'; - console.log ('display: block'); } else { document.getElementById('credentials').style.display = 'none'; - console.log ('display: none'); } }).on('data', function(data) { term.write(data); + if (sessionLogEnable) { + sessionLog = sessionLog + data; + } }).on('disconnect', function() { document.getElementById('status').style.backgroundColor = 'red'; - document.getElementById('status').innerHTML = 'WEBSOCKET SERVER DISCONNECTED'; + document.getElementById('status').innerHTML = 'WEBSOCKET SERVER DISCONNECTED' + err; socket.io.reconnection(false); }).on('error', function(err) { document.getElementById('status').style.backgroundColor = 'red'; document.getElementById('status').innerHTML = 'ERROR ' + err; }); -}); +}); \ No newline at end of file diff --git a/public/style.css b/public/style.css index 0766e1a..a422a27 100644 --- a/public/style.css +++ b/public/style.css @@ -89,4 +89,36 @@ body { a.credentials { color: rgb(51, 51, 51); text-decoration: none; -} \ No newline at end of file +} +#downloadLog { + display: inline-block; + color: rgb(240, 240, 240); + background-color: rgb(255, 127, 0); + padding-left: 10px; + padding-right: 10px; + border-color: white; + border-style: none solid none none; + border-width: 1px; + text-align: left; + z-index: 100; +} +a.downloadLog { + color: rgb(240, 240, 240); + text-decoration: none; +} +#startLog { + display: inline-block; + color: rgb(240, 240, 240); + background-color: rgb(0, 127, 0); + padding-left: 10px; + padding-right: 10px; + border-color: white; + border-style: none solid none none; + border-width: 1px; + text-align: left; + z-index: 100; +} +a.startLog { + color: rgb(240, 240, 240); + text-decoration: none; +}