From 638fafb95d0f0c7ef6cd34d05b548d082212bfe6 Mon Sep 17 00:00:00 2001 From: billchurch Date: Wed, 18 May 2016 11:34:49 -0400 Subject: [PATCH] Initial Commit Initial Commit --- .gitignore | 37 +++++++++++++++++ index.js | 104 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 19 +++++++++ public/client.htm | 22 ++++++++++ public/client.js | 33 +++++++++++++++ public/style.css | 66 +++++++++++++++++++++++++++++ 6 files changed, 281 insertions(+) create mode 100644 .gitignore create mode 100644 index.js create mode 100644 package.json create mode 100644 public/client.htm create mode 100644 public/client.js create mode 100644 public/style.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e9a3d6e --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..1a81a27 --- /dev/null +++ b/index.js @@ -0,0 +1,104 @@ +var express = require('express'); +var app = express(); +var server = require('http').Server(app); +var io = require('socket.io')(server); +var path = require('path'); +var basicAuth = require('basic-auth'); +var term = require('term.js'); +var ssh = require('ssh2'); + +var username = null; +var password = null; +var host = null; +var port = 22; +var header = 'Default Header'; +var headerBackground = 'rgb (0,90,0)'; + +function checkParams(arr) { + return function(req, res, next) { + // Make sure each param listed in arr is present in req.query + var missing_params = []; + for (var i = 0; i < arr.length; i++) { + if (!eval("req.query." + arr[i])) { + missing_params.push(arr[i]); + } + } + if (missing_params.length == 0) { + next(); + } else { + next(JSON.stringify({ + "error": "query error", + "message": "Parameter(s) missing: " + missing_params.join(",") + })); + } + } +} + +server.listen({ + host: '127.0.0.1', + port: 2222 +}); + +app.use(express.static(__dirname + '/public')).use(term.middleware()).use(function(req, res, next) { + var myAuth = basicAuth(req); + if (myAuth === undefined) { + res.statusCode = 401; + res.setHeader('WWW-Authenticate', 'Basic realm="WebSSH"'); + res.end('Username and password required for web SSH service.'); + } else { + username = myAuth['name']; + password = myAuth['pass']; + next(); + } +}).get('/', checkParams(["host"]), function(req, res) { + res.sendFile(path.join(__dirname + '/public/client.htm')) + host = req.query.host + if (typeof req.query.port !== 'undefined' && req.query.port !== null){ port = req.query.port;} + if (typeof req.query.header !== 'undefined' && req.query.header !== null){ header = req.query.header;} + if (typeof req.query.headerBackground !== 'undefined' && req.query.headerBackground !== null){ headerBackground = req.query.headerBackground;} + // debug // console.log('varibles passwd: ' + username + '/' + host + '/' + port); +}); + +io.on('connection', function(socket) { + var conn = new ssh(); + conn.on('banner', function(msg, lng) { + socket.emit('data', msg); + }).on('ready', function() { + socket.emit('title', 'ssh://' + host); + socket.emit('headerBackground', headerBackground); + socket.emit('header', header); + socket.emit('footer', 'ssh://' + username + '@' + host + ':' + port); + socket.emit('status', 'SSH CONNECTION ESTABLISHED'); + socket.emit('statusBackground', 'green'); + conn.shell(function(err, stream) { + if (err) return socket.emit('status', 'SSH EXEC ERROR: ' + err.message).emit('statusBackground', 'red'); + socket.on('data', function(data) { + stream.write(data); + }); + stream.on('data', function(d) { + socket.emit('data', d.toString('binary')); + }).on('close', function() { + conn.end(); + }); + }); + }).on('end', function() { + socket.emit('status', 'SSH CONNECTION CLOSED BY HOST'); + socket.emit('statusBackground', 'red'); + }).on('close', function() { + socket.emit('status', 'SSH CONNECTION CLOSED'); + socket.emit('statusBackground', 'red'); + }).on('error', function(error) { + socket.emit('status', 'SSH CONNECTION ERROR - ' + error) + socket.emit('statusBackground', 'red'); + }).connect({ + host: host, + port: port, + username: username, + password: password, +// some cisco routers need the these cipher strings + algorithms: { + 'cipher': ['aes128-cbc', '3des-cbc', 'aes256-cbc'], + 'hmac': ['hmac-sha1', 'hmac-sha1-96', 'hmac-md5-96'] + } + }); +}); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..6917736 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "BIG-IP-comments": [ + "package.json is the standard npm (www.npmjs.org) package definition file.", + "For more information please see www.npmjs.org/doc/package.json.html. " + ], + "description": "A custom iRulesLX extension for BIG-IP", + "private": true, + "repository": {}, + "engines": { + "node": "0.11.12" + }, + "dependencies": { + "basic-auth": "^1.0.3", + "express": "^4.13.4", + "socket.io": "^1.4.5", + "ssh2": "^0.5.0", + "term.js": "0.0.7" + } +} diff --git a/public/client.htm b/public/client.htm new file mode 100644 index 0000000..72859bb --- /dev/null +++ b/public/client.htm @@ -0,0 +1,22 @@ + + + Web SSH + + + + + + + + +
+ +
+
+ +
+
+ + \ No newline at end of file diff --git a/public/client.js b/public/client.js new file mode 100644 index 0000000..5bc0cce --- /dev/null +++ b/public/client.js @@ -0,0 +1,33 @@ +var client = {}; +client.run = function(options) { + options = options || {}; + window.addEventListener('load', function() { + var socket = io.connect(); + socket.on('connect', function() { + var term = new Terminal(); + term.on('data', function(data) { + socket.emit('data', data); + }); + socket.on('title', function(data) { + document.title = data; + }).on('status', function(data) { + document.getElementById('status').innerHTML = data; + }).on('headerBackground', function(data) { + document.getElementById('header').style.backgroundColor = data; + }).on('header', function(data) { + document.getElementById('header').innerHTML = data; + }).on('footer', function(data) { + document.getElementById('footer').innerHTML = data; + }).on('statusBackground', function(data) { + document.getElementById('status').style.backgroundColor = data; + }); + term.open(document.getElementById("terminal")); + socket.on('data', function(data) { + term.write(data); + }).on('disconnect', function() { + document.getElementById('status').innerHTML = 'WEBSOCKET SERVER DISCONNECTED'; + socket.io.reconnection(false); + }); + }); + }, false); +} \ No newline at end of file diff --git a/public/style.css b/public/style.css new file mode 100644 index 0000000..d80753e --- /dev/null +++ b/public/style.css @@ -0,0 +1,66 @@ +body { + font-family: helvetica, sans-serif, arial; + font-size: 1em; + color: #111; + background-color: rgb(0, 0, 0); + color: rgb(240, 240, 240); +} + +#header { + color: rgb(240, 240, 240); + background-color: rgb(0, 128, 0); + width: 100%; + border-color: white; + border-style: none none solid none; + border-width: 1px; + text-align: center; + z-index: 99; +} + +#terminal { + width: 960px; + height: 600px; + margin: 0 auto; + padding: 2px; +} + +#terminal .terminal { + background-color: #111; + color: #fafafa; + padding: 2px; +} + +#terminal .terminal .terminal-cursor { + background-color: #fafafa; +} + +#bottomdiv { + width: 100%; + background-color: rgb(50, 50, 50); + border-color: white; + border-style: solid none none none; + border-width: 1px; + z-index: 99; +} + +#footer { + display: inline-block; + color: rgb(240, 240, 240); + background-color: rgb(50, 50, 50); + padding-left: 10px; + padding-right: 10px; + text-align: left; +} + +#status { + display: inline-block; + color: rgb(240, 240, 240); + background-color: rgb(50, 50, 50); + padding-left: 10px; + padding-right: 10px; + border-color: white; + border-style: none solid none solid; + border-width: 1px; + text-align: left; + z-index: 100; +} \ No newline at end of file