updated documents, added validation to user input strings

term= query option to specify TERM environment variable for host, valid
strings are alpha-numeric with a hypen (validated). Otherwise the
default ssh.term variable from `config.json` will be used.
- validation for host (v4,v6,fqdn,hostname), port (integer 2-65535),
and header (sanatized) from URL input
This commit is contained in:
billchurch 2017-05-27 18:12:02 -04:00
parent a0b0ec8632
commit 4540cc6e0e
12 changed files with 30 additions and 20 deletions

View file

@ -2,6 +2,7 @@
## [Unreleased] ## [Unreleased]
### Added ### Added
- This ChangeLog.md file - This ChangeLog.md file
- Support for UTF-8 characters (thanks @bara666)
- Snyk, Bithound, Travis CI - Snyk, Bithound, Travis CI
- Cross platform improvements (path mappings) - Cross platform improvements (path mappings)
- Session fixup between Express and Socket.io - Session fixup between Express and Socket.io
@ -11,6 +12,8 @@
and events in the application (not including the ssh2 module debug) and events in the application (not including the ssh2 module debug)
- using Grunt to pull js and css source files from other modules `npm run build` to rebuild these if changed or updated. - using Grunt to pull js and css source files from other modules `npm run build` to rebuild these if changed or updated.
- `useminified` option in `config.json` to enable using minified client side javascript (true) defaults to false (non-minified) - `useminified` option in `config.json` to enable using minified client side javascript (true) defaults to false (non-minified)
- term= query option to specify TERM environment variable for host, valid strings are alpha-numeric with a hypen (validated). Otherwise the default ssh.term variable from `config.json` will be used.
- validation for host (v4,v6,fqdn,hostname), port (integer 2-65535), and header (sanatized) from URL input
### Changed ### Changed
- error handling in public/client.js - error handling in public/client.js
@ -25,10 +28,12 @@ and events in the application (not including the ssh2 module debug)
- sourcemaps of all minified code (in /public/src and /public/src/js) - sourcemaps of all minified code (in /public/src and /public/src/js)
- renamed `client.htm` to `client-full.htm` - renamed `client.htm` to `client-full.htm`
- created `client-min.htm` to serve minified javascript - created `client-min.htm` to serve minified javascript
- if header.text is null in config.json and header is not defined as a get parameter the Header will not be displayed. Both of these must be null / undefined and not specified as get parameters.
### Fixed ### Fixed
- Multiple errors may ovewrite status bar which would cause confusion as to what originally caused the error. Example, ssh server disconnects which prompts a cascade of events (conn.on('end'), socket.on('disconnect'), conn.on('close')) and the original reason (conn.on('end')) would be lost and the user would erroneously receive a WEBSOCKET error as the last event to fire would be the websocket connection closing from the app. - Multiple errors may ovewrite status bar which would cause confusion as to what originally caused the error. Example, ssh server disconnects which prompts a cascade of events (conn.on('end'), socket.on('disconnect'), conn.on('close')) and the original reason (conn.on('end')) would be lost and the user would erroneously receive a WEBSOCKET error as the last event to fire would be the websocket connection closing from the app.
- ensure ssh session is closed when a browser disconnects from the websocket - ensure ssh session is closed when a browser disconnects from the websocket
- if headerBackground is changed, status background is changed to the same color (typo, fixed)
### Removed ### Removed
- Express Static References directly to module source directories due to concatenating and minifying js/css - Express Static References directly to module source directories due to concatenating and minifying js/css

View file

@ -23,11 +23,11 @@ You will be prompted for credentials to use on the SSH server via HTTP Basic aut
# Options (GET request vars) # Options (GET request vars)
port= - port of SSH server (defaults to 22) * **port=** - _integer_ - port of SSH server (defaults to 22)
header= - optional header to display on page * **header=** - _string_ - optional header to display on page
headerBackground= - optional background color of header to display on page * **headerBackground=** - _string_ - optional background color of header to display on page
# Config File Options # Config File Options
`config.json` contains several options which may be specified to customize to your needs, vs editing the javascript direclty. This is JSON format so mind your spacing, brackets, etc... `config.json` contains several options which may be specified to customize to your needs, vs editing the javascript direclty. This is JSON format so mind your spacing, brackets, etc...
@ -48,7 +48,7 @@ headerBackground= - optional background color of header to display on page
* **useminified** - _boolean_ - Choose between ./public/client-full.htm (false/non-minified) or ./public/client-min.htm (true/minified js), defaults to false (non-minified version) * **useminified** - _boolean_ - Choose between ./public/client-full.htm (false/non-minified) or ./public/client-min.htm (true/minified js), defaults to false (non-minified version)
* **header.text** - _string_ - Specify header text, defaults to `My Header` but may also be set to `null`. * **header.text** - _string_ - Specify header text, defaults to `My Header` but may also be set to `null`. When set to `null` no header bar will be displayed on the client.
* **header.background** - _string_ - Header background, defaults to `green`. * **header.background** - _string_ - Header background, defaults to `green`.

View file

@ -14,7 +14,7 @@
}, },
"useminified": false, "useminified": false,
"header": { "header": {
"text": "My Header", "text": null,
"background": "green" "background": "green"
}, },
"session": { "session": {

View file

@ -11,6 +11,7 @@ var path = require('path')
var config = require('read-config')(path.join(__dirname, 'config.json')) var config = require('read-config')(path.join(__dirname, 'config.json'))
var myutil = require('./util') var myutil = require('./util')
var socket = require('./socket/index.js') var socket = require('./socket/index.js')
var validator = require('validator')
var session = require('express-session')({ var session = require('express-session')({
secret: config.session.secret, secret: config.session.secret,
name: config.session.name, name: config.session.name,
@ -40,17 +41,21 @@ app.disable('x-powered-by')
app.get('/ssh/host/:host?', function (req, res, next) { app.get('/ssh/host/:host?', function (req, res, next) {
res.sendFile(path.join(path.join(__dirname, 'public', (config.useminified) ? 'client-min.htm' : 'client-full.htm'))) res.sendFile(path.join(path.join(__dirname, 'public', (config.useminified) ? 'client-min.htm' : 'client-full.htm')))
// capture and assign variables // capture and assign variables
myHost = validator.isIP(req.params.host) ? req.params.host : undefined
console.log('req.params.host: ', myHost)
req.session.ssh = { req.session.ssh = {
host: req.params.host || config.ssh.host, host: validator.isIP(req.params.host + '') && req.params.host || validator.isFQDN(req.params.host) && req.params.host || /^(([a-z]|[A-Z]|[0-9]|[!^(){}\-_~])+)?\w$/.test(req.params.host) && req.params.host || config.ssh.host,
port: req.query.port || config.ssh.port, port: validator.isInt(req.query.port + '', {min: 1, max: 65535}) && req.query.port || config.ssh.port,
header: { header: {
name: req.query.header || config.header.text, name: req.query.header || config.header.text,
background: req.query.headerBackground || config.header.background background: req.query.headerBackground || config.header.background
}, },
algorithms: config.algorithms, algorithms: config.algorithms,
term: config.ssh.term, term: /^(([a-z]|[A-Z]|[0-9]|[!^(){}\-_~])+)?\w$/.test(req.query.sshterm) && req.query.sshterm || config.ssh.term,
allowreplay: req.headers.allowreplay || false allowreplay: validator.isBoolean(req.headers.allowreplay + '') || false
} }
req.session.ssh.header.name && validator.escape(req.session.ssh.header.name)
req.session.ssh.header.background && validator.escape(req.session.ssh.header.background)
}) })
// static files // static files

View file

@ -34,7 +34,8 @@
"express-session": "^1.15.3", "express-session": "^1.15.3",
"read-config": "^1.6.0", "read-config": "^1.6.0",
"socket.io": "^1.6.0", "socket.io": "^1.6.0",
"ssh2": "^0.5.4" "ssh2": "^0.5.4",
"validator": "^7.0.0"
}, },
"scripts": { "scripts": {
"start": "node index", "start": "node index",

View file

@ -99,7 +99,7 @@ socket.on('connect', function () {
}).on('statusBackground', function (data) { }).on('statusBackground', function (data) {
document.getElementById('status').style.backgroundColor = data document.getElementById('status').style.backgroundColor = data
}).on('allowreplay', function (data) { }).on('allowreplay', function (data) {
if (data === 'true') { if (data == true) {
console.log('allowreplay: ' + data) console.log('allowreplay: ' + data)
document.getElementById('credentials').style.display = 'inline' document.getElementById('credentials').style.display = 'inline'
} else { } else {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -12605,7 +12605,7 @@ socket.on('connect', function () {
}).on('statusBackground', function (data) { }).on('statusBackground', function (data) {
document.getElementById('status').style.backgroundColor = data document.getElementById('status').style.backgroundColor = data
}).on('allowreplay', function (data) { }).on('allowreplay', function (data) {
if (data === 'true') { if (data == true) {
console.log('allowreplay: ' + data) console.log('allowreplay: ' + data)
document.getElementById('credentials').style.display = 'inline' document.getElementById('credentials').style.display = 'inline'
} else { } else {

File diff suppressed because one or more lines are too long

View file

@ -51,13 +51,12 @@ module.exports = function (socket) {
conn.on('ready', function () { conn.on('ready', function () {
console.log('webssh2 Login: user=' + socket.request.session.username + ' from=' + socket.handshake.address + ' host=' + socket.request.session.ssh.host + ' port=' + socket.request.session.ssh.port + ' sessionID=' + socket.request.sessionID + '/' + socket.id + ' allowreplay=' + socket.request.session.ssh.allowreplay + ' term=' + socket.request.session.ssh.term) console.log('webssh2 Login: user=' + socket.request.session.username + ' from=' + socket.handshake.address + ' host=' + socket.request.session.ssh.host + ' port=' + socket.request.session.ssh.port + ' sessionID=' + socket.request.sessionID + '/' + socket.id + ' allowreplay=' + socket.request.session.ssh.allowreplay + ' term=' + socket.request.session.ssh.term)
socket.emit('title', 'ssh://' + socket.request.session.ssh.host) socket.emit('title', 'ssh://' + socket.request.session.ssh.host)
socket.emit('headerBackground', socket.request.session.ssh.header.background) socket.request.session.ssh.header.background && socket.emit('headerBackground', socket.request.session.ssh.header.background)
socket.emit('header', socket.request.session.ssh.header.name) socket.request.session.ssh.header.name && socket.emit('header', socket.request.session.ssh.header.name)
socket.emit('footer', 'ssh://' + socket.request.session.username + '@' + socket.request.session.ssh.host + ':' + socket.request.session.ssh.port) socket.emit('footer', 'ssh://' + socket.request.session.username + '@' + socket.request.session.ssh.host + ':' + socket.request.session.ssh.port)
socket.emit('status', 'SSH CONNECTION ESTABLISHED') socket.emit('status', 'SSH CONNECTION ESTABLISHED')
socket.emit('statusBackground', socket.request.session.ssh.header.background) socket.emit('statusBackground', 'green')
socket.emit('allowreplay', socket.request.session.ssh.allowreplay) socket.emit('allowreplay', socket.request.session.ssh.allowreplay)
conn.shell({ conn.shell({
term: socket.request.session.ssh.term, term: socket.request.session.ssh.term,
cols: termCols, cols: termCols,

View file

@ -99,7 +99,7 @@ socket.on('connect', function () {
}).on('statusBackground', function (data) { }).on('statusBackground', function (data) {
document.getElementById('status').style.backgroundColor = data document.getElementById('status').style.backgroundColor = data
}).on('allowreplay', function (data) { }).on('allowreplay', function (data) {
if (data === 'true') { if (data == true) {
console.log('allowreplay: ' + data) console.log('allowreplay: ' + data)
document.getElementById('credentials').style.display = 'inline' document.getElementById('credentials').style.display = 'inline'
} else { } else {