reauth feature
fixes #75 and potentially #51 thanks to both @vbeskrovny and @vvalchev
This commit is contained in:
parent
a518f0748f
commit
9bbc116120
8 changed files with 36 additions and 23 deletions
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
||||||
.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{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}
|
.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}
|
|
@ -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;
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
"secret": "mysecret"
|
"secret": "mysecret"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"challengeButton": true
|
"challengeButton": true,
|
||||||
|
"allowreauth": true
|
||||||
},
|
},
|
||||||
"algorithms": {
|
"algorithms": {
|
||||||
"kex": [
|
"kex": [
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
"builddev": "webpack --progress --colors --config scripts/webpack.dev.js",
|
"builddev": "webpack --progress --colors --config scripts/webpack.dev.js",
|
||||||
"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": {
|
||||||
|
@ -78,7 +78,8 @@
|
||||||
"bigip/*",
|
"bigip/*",
|
||||||
"screenshots/*",
|
"screenshots/*",
|
||||||
"bin/*",
|
"bin/*",
|
||||||
"build/*"
|
"build/*",
|
||||||
|
"workspace/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,16 +36,8 @@ app.disable('x-powered-by')
|
||||||
app.use(express.static(publicPath, expressOptions))
|
app.use(express.static(publicPath, expressOptions))
|
||||||
|
|
||||||
app.get('/reauth', function (req, res, next) {
|
app.get('/reauth', function (req, res, next) {
|
||||||
var r = req.headers.referer || '/';
|
var r = req.headers.referer || '/'
|
||||||
res.status(401).send(
|
res.status(401).send('<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=' + r + '"></head><body bgcolor="#000"></body></html>');
|
||||||
'<html>' +
|
|
||||||
' <head>' +
|
|
||||||
' <meta http-equiv="refresh" content="1; url=' + r + '" />' +
|
|
||||||
' </head>' +
|
|
||||||
' <body>' +
|
|
||||||
' <a href="' + r + '">Go Back</a>' +
|
|
||||||
' </body>' +
|
|
||||||
'</html>');
|
|
||||||
})
|
})
|
||||||
|
|
||||||
app.get('/ssh/host/:host?', function (req, res, next) {
|
app.get('/ssh/host/:host?', function (req, res, next) {
|
||||||
|
@ -73,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,
|
||||||
|
|
|
@ -8,8 +8,7 @@ var SSH = require('ssh2').Client
|
||||||
// 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>' +
|
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>' +
|
'<a id="downloadLogBtn"><i class="fas fa-download fa-fw"></i> Download Log</a>'
|
||||||
'<a style="color:black" href="/reauth"><i class="fas fa-key fa-fw"></i> Switch User</a>';
|
|
||||||
|
|
||||||
// public
|
// public
|
||||||
module.exports = function socket (socket) {
|
module.exports = function socket (socket) {
|
||||||
|
@ -42,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,
|
||||||
|
|
Loading…
Reference in a new issue