Merge remote-tracking branch 'origin/master' into package-upgrade-test

This commit is contained in:
Bill Church 2018-08-07 06:50:51 -04:00
commit 806c9f0b42
10 changed files with 56 additions and 12 deletions

View file

@ -1,4 +1,12 @@
# Change Log # Change Log
## [0.2.5] TBD
### Added
- Reauth function thanks to @vbeskrovny and @vvalchev (9bbc116)
- Controlled by `config.json` option `options.allowreauth` true presents reauth dialog and false hides dialog
### Changed
- `options.challengeButton` enabled
- previously this configuraiton option did nothing, this now enables the Credentials button site-wide regardless of the `allowreplay` header value
## [0.2.4] 2018-07-18 ## [0.2.4] 2018-07-18
### Added ### Added
- Browser title window now changes with xterm escape sequences (see http://tldp.org/HOWTO/Xterm-Title-3.html) - Browser title window now changes with xterm escape sequences (see http://tldp.org/HOWTO/Xterm-Title-3.html)

View file

@ -1,5 +1,5 @@
# WebSSH2 # WebSSH2
[![GitHub version](https://badge.fury.io/gh/billchurch%2Fwebssh2.svg)](https://badge.fury.io/gh/billchurch%2Fwebssh2) [![Build Status](https://travis-ci.org/billchurch/WebSSH2.svg?branch=master)](https://travis-ci.org/billchurch/WebSSH2) [![Known Vulnerabilities](https://snyk.io/test/github/billchurch/webssh2/badge.svg)](https://snyk.io/test/github/billchurch/webssh2) [![bitHound Overall Score](https://www.bithound.io/github/billchurch/WebSSH2/badges/score.svg)](https://www.bithound.io/github/billchurch/WebSSH2) [![bitHound Dependencies](https://www.bithound.io/github/billchurch/WebSSH2/badges/dependencies.svg)](https://www.bithound.io/github/billchurch/WebSSH2/master/dependencies/npm) [![NSP Status](https://nodesecurity.io/orgs/billchurch/projects/b0a0d9df-1340-43ef-9736-ef983c057764/badge)](https://nodesecurity.io/orgs/billchurch/projects/b0a0d9df-1340-43ef-9736-ef983c057764) [![Greenkeeper badge](https://badges.greenkeeper.io/billchurch/WebSSH2.svg)](https://greenkeeper.io/) [![GitHub version](https://badge.fury.io/gh/billchurch%2Fwebssh2.svg)](https://badge.fury.io/gh/billchurch%2Fwebssh2) [![Build Status](https://travis-ci.org/billchurch/WebSSH2.svg?branch=master)](https://travis-ci.org/billchurch/WebSSH2) [![Known Vulnerabilities](https://snyk.io/test/github/billchurch/webssh2/badge.svg)](https://snyk.io/test/github/billchurch/webssh2) [![NSP Status](https://nodesecurity.io/orgs/billchurch/projects/b0a0d9df-1340-43ef-9736-ef983c057764/badge)](https://nodesecurity.io/orgs/billchurch/projects/b0a0d9df-1340-43ef-9736-ef983c057764) [![Greenkeeper badge](https://badges.greenkeeper.io/billchurch/WebSSH2.svg)](https://greenkeeper.io/)
Web SSH Client using ssh2, socket.io, xterm.js, and express Web SSH Client using ssh2, socket.io, xterm.js, and express

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,4 @@
<<<<<<< HEAD
/** /**
* Copyright (c) 2014 The xterm.js authors. All rights reserved. * Copyright (c) 2014 The xterm.js authors. All rights reserved.
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
@ -287,3 +288,6 @@ html, body {
.dropup:hover .dropbtn { .dropup:hover .dropbtn {
background-color: #3e8e41; background-color: #3e8e41;
} }
=======
.xterm{font-family:courier-new,courier,monospace;font-feature-settings:"liga" 0;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:10}.xterm .xterm-helper-textarea{position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-10;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm:not(.enable-mouse-events){cursor:text}.xterm .xterm-accessibility,.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:100;color:transparent}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-cursor-pointer{cursor:pointer}body,html{font-family:helvetica,sans-serif;font-size:1em;color:#111;background-color:#000;color:#f0f0f0;height:100%;margin:0}#header{color:#f0f0f0;background-color:green;width:100%;border-color:#fff;border-style:none none solid;border-width:1px;text-align:center;flex:0 1 auto;z-index:99;height:19px;display:none}.box{display:block;height:100%}#terminal-container{display:block;width:calc(1 - 1 px);margin:0 auto;padding:2px;height:calc(100% - 19px)}#terminal-container .terminal{background-color:#000;color:#fafafa;padding:2px;height:calc(100% - 19px)}#terminal-container .terminal:focus .terminal-cursor{background-color:#fafafa}#bottomdiv{position:fixed;left:0;bottom:0;width:100%;background-color:#323232;border-color:#fff;border-style:solid none none;border-width:1px;z-index:99;height:19px}#footer{padding-left:5px;padding-right:5px;border-style:none none none solid}#footer,#status{display:inline-block;color:#f0f0f0;background-color:#323232;border-color:#fff;border-width:1px;text-align:left}#status{padding-right:10px;border-style:none solid}#menu,#status{padding-left:10px;z-index:100}#menu{display:inline-block;font-size:16px;color:#fff}#menu:hover .dropup-content{display:block}#credentialsBtn,#logBtn,#reauthBtn{color:#000}.dropup{position:relative;display:inline-block;cursor:pointer}.dropup-content{display:none;position:absolute;background-color:#f1f1f1;font-size:16px;min-width:160px;bottom:18px;z-index:101}.dropup-content a{color:#777;padding:12px 16px;text-decoration:none;display:block}.dropup-content a:hover{background-color:#ccc}.dropup:click .dropup-content,.dropup:hover .dropup-content{display:block}.dropup:hover .dropbtn{background-color:#3e8e41}
>>>>>>> origin/master

View file

@ -85,12 +85,10 @@ html, body {
#menu:hover .dropup-content { #menu:hover .dropup-content {
display: block; display: block;
} }
#logBtn { #logBtn, #credentialsBtn, #reauthBtn {
color: #000;
}
#credentialsBtn {
color: #000; color: #000;
} }
.dropup { .dropup {
position: relative; position: relative;
display: inline-block; display: inline-block;

View file

@ -19,10 +19,11 @@ require('../css/style.css')
Terminal.applyAddon(fit) Terminal.applyAddon(fit)
/* global Blob, logBtn, credentialsBtn, downloadLogBtn */ /* global Blob, logBtn, credentialsBtn, reauthBtn, downloadLogBtn */
var sessionLogEnable = false var sessionLogEnable = false
var loggedData = false var loggedData = false
var allowreplay = false var allowreplay = false
var allowreauth = false
var sessionLog, sessionFooter, logDate, currentDate, myFile, errorExists var sessionLog, sessionFooter, logDate, currentDate, myFile, errorExists
var socket, termid // eslint-disable-line var socket, termid // eslint-disable-line
var term = new Terminal() var term = new Terminal()
@ -128,6 +129,17 @@ socket.on('allowreplay', function (data) {
} }
}) })
socket.on('allowreauth', function (data) {
if (data === true) {
console.log('allowreauth: ' + data)
allowreauth = true
drawMenu(dropupContent.innerHTML + '<a id="reauthBtn"><i class="fas fa-key fa-fw"></i> Switch User</a>')
} else {
allowreauth = false
console.log('allowreauth: ' + data)
}
})
socket.on('disconnect', function (err) { socket.on('disconnect', function (err) {
if (!errorExists) { if (!errorExists) {
status.style.backgroundColor = 'red' status.style.backgroundColor = 'red'
@ -153,10 +165,18 @@ term.on('title', function (title) {
function drawMenu (data) { function drawMenu (data) {
dropupContent.innerHTML = data dropupContent.innerHTML = data
logBtn.addEventListener('click', toggleLog) logBtn.addEventListener('click', toggleLog)
allowreauth && reauthBtn.addEventListener('click', reauthSession)
allowreplay && credentialsBtn.addEventListener('click', replayCredentials) allowreplay && credentialsBtn.addEventListener('click', replayCredentials)
loggedData && downloadLogBtn.addEventListener('click', downloadLog) loggedData && downloadLogBtn.addEventListener('click', downloadLog)
} }
// reauthenticate
function reauthSession () { // eslint-disable-line
console.log('re-authenticating')
window.location.href = '/reauth'
return false
}
// replay password to server, requires // replay password to server, requires
function replayCredentials () { // eslint-disable-line function replayCredentials () { // eslint-disable-line
socket.emit('control', 'replayCredentials') socket.emit('control', 'replayCredentials')

View file

@ -30,7 +30,8 @@
"secret": "mysecret" "secret": "mysecret"
}, },
"options": { "options": {
"challengeButton": true "challengeButton": true,
"allowreauth": true
}, },
"algorithms": { "algorithms": {
"kex": [ "kex": [

View file

@ -46,7 +46,7 @@
"analyze": "webpack --json --config scripts/webpack.prod.js | webpack-bundle-size-analyzer", "analyze": "webpack --json --config scripts/webpack.prod.js | webpack-bundle-size-analyzer",
"test": "snyk test", "test": "snyk test",
"watch": "nodemon index.js", "watch": "nodemon index.js",
"standard": "standard --verbose | snazzy", "standard": "standard --verbose --fix | snazzy",
"cleanmac": "find . -name '.DS_Store' -type f -delete" "cleanmac": "find . -name '.DS_Store' -type f -delete"
}, },
"devDependencies": { "devDependencies": {
@ -79,7 +79,8 @@
"bigip/*", "bigip/*",
"screenshots/*", "screenshots/*",
"bin/*", "bin/*",
"build/*" "build/*",
"workspace/*"
] ]
} }
} }

View file

@ -35,6 +35,11 @@ app.disable('x-powered-by')
// static files // static files
app.use(express.static(publicPath, expressOptions)) app.use(express.static(publicPath, expressOptions))
app.get('/reauth', function (req, res, next) {
var r = req.headers.referer || '/'
res.status(401).send('<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=' + r + '"></head><body bgcolor="#000"></body></html>');
})
app.get('/ssh/host/:host?', function (req, res, next) { app.get('/ssh/host/:host?', function (req, res, next) {
res.sendFile(path.join(path.join(publicPath, 'client.htm'))) res.sendFile(path.join(path.join(publicPath, 'client.htm')))
// capture, assign, and validated variables // capture, assign, and validated variables
@ -60,7 +65,8 @@ app.get('/ssh/host/:host?', function (req, res, next) {
tabStopWidth: (validator.isInt(req.query.tabStopWidth + '', {min: 1, max: 100}) && req.query.tabStopWidth) ? req.query.tabStopWidth : config.terminal.tabStopWidth, tabStopWidth: (validator.isInt(req.query.tabStopWidth + '', {min: 1, max: 100}) && req.query.tabStopWidth) ? req.query.tabStopWidth : config.terminal.tabStopWidth,
bellStyle: ((req.query.bellStyle) && (['sound', 'none'].indexOf(req.query.bellStyle) > -1)) ? req.query.bellStyle : config.terminal.bellStyle bellStyle: ((req.query.bellStyle) && (['sound', 'none'].indexOf(req.query.bellStyle) > -1)) ? req.query.bellStyle : config.terminal.bellStyle
}, },
allowreplay: (validator.isBoolean(req.headers.allowreplay + '') ? myutil.parseBool(req.headers.allowreplay) : false), allowreplay: config.options.challengeButton || (validator.isBoolean(req.headers.allowreplay + '') ? myutil.parseBool(req.headers.allowreplay) : false),
allowreauth: config.options.allowreauth || false,
mrhsession: ((validator.isAlphanumeric(req.headers.mrhsession + '') && req.headers.mrhsession) ? req.headers.mrhsession : 'none'), mrhsession: ((validator.isAlphanumeric(req.headers.mrhsession + '') && req.headers.mrhsession) ? req.headers.mrhsession : 'none'),
serverlog: { serverlog: {
client: config.serverlog.client || false, client: config.serverlog.client || false,

View file

@ -7,7 +7,8 @@ var SSH = require('ssh2').Client
// var fs = require('fs') // var fs = require('fs')
// var hostkeys = JSON.parse(fs.readFileSync('./hostkeyhashes.json', 'utf8')) // var hostkeys = JSON.parse(fs.readFileSync('./hostkeyhashes.json', 'utf8'))
var termCols, termRows var termCols, termRows
var menuData = '<a id="logBtn"><i class="fas fa-clipboard fa-fw"></i> Start Log</a><a id="downloadLogBtn"><i class="fas fa-download fa-fw"></i> Download Log</a>' var menuData = '<a id="logBtn"><i class="fas fa-clipboard fa-fw"></i> Start Log</a>' +
'<a id="downloadLogBtn"><i class="fas fa-download fa-fw"></i> Download Log</a>'
// public // public
module.exports = function socket (socket) { module.exports = function socket (socket) {
@ -40,6 +41,7 @@ module.exports = function socket (socket) {
socket.emit('status', 'SSH CONNECTION ESTABLISHED') socket.emit('status', 'SSH CONNECTION ESTABLISHED')
socket.emit('statusBackground', 'green') socket.emit('statusBackground', 'green')
socket.emit('allowreplay', socket.request.session.ssh.allowreplay) socket.emit('allowreplay', socket.request.session.ssh.allowreplay)
socket.emit('allowreauth', socket.request.session.ssh.allowreauth)
conn.shell({ conn.shell({
term: socket.request.session.ssh.term, term: socket.request.session.ssh.term,
cols: termCols, cols: termCols,