codelint and cross platform improvements

Used [standard](https://github.com/feross/standard) to lint some of the
code.

Cross-platform directory handling (updated references to filesystem
paths to use path.join)
This commit is contained in:
billchurch 2017-05-08 12:03:18 -07:00
parent cef50b870c
commit aad3744552
2 changed files with 235 additions and 235 deletions

272
index.js
View file

@ -4,148 +4,148 @@
*
*/
var express = require('express'),
app = express(),
cookieParser = require('cookie-parser'),
server = require('http').Server(app),
io = require('socket.io')(server),
path = require('path'),
basicAuth = require('basic-auth'),
ssh = require('ssh2').Client,
readConfig = require('read-config'),
config = readConfig(__dirname + '/config.json'),
myError = " - ",
termCols,
termRows;
app = express(),
cookieParser = require('cookie-parser'),
server = require('http').Server(app),
io = require('socket.io')(server),
path = require('path'),
basicAuth = require('basic-auth'),
ssh = require('ssh2').Client,
readConfig = require('read-config'),
config = readConfig(path.join(__dirname, 'config.json')),
myError = ' - ',
termCols,
termRows
function logErrors(err, req, res, next) {
console.error(err.stack);
next(err);
}
// function logErrors (err, req, res, next) {
// console.error(err.stack)
// next(err)
// }
server.listen({
host: config.listen.ip,
port: config.listen.port
}).on('error', function(err) {
if (err.code === 'EADDRINUSE') {
config.listen.port++;
console.log('Address in use, retrying on port ' + config.listen.port);
setTimeout(function() {
server.listen(config.listen.port);
}, 250);
}
});
host: config.listen.ip,
port: config.listen.port
}).on('error', function (err) {
if (err.code === 'EADDRINUSE') {
config.listen.port++
console.log('Address in use, retrying on port ' + config.listen.port)
setTimeout(function () {
server.listen(config.listen.port)
}, 250)
}
})
app.use(express.static(__dirname + '/public')).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 if (myAuth.name === "") {
res.statusCode = 401;
res.setHeader('WWW-Authenticate', 'Basic realm="WebSSH"');
res.end('Username and password required for web SSH service.');
} else {
config.user.name = myAuth.name;
config.user.password = myAuth.pass;
next();
}
}).use(cookieParser()).get('/ssh/host/:host?', function(req, res) {
res.sendFile(path.join(__dirname + '/public/client.htm'));
config.ssh.host = req.params.host;
if (typeof req.query.port !== 'undefined' && req.query.port !== null) {
config.ssh.port = req.query.port;
}
if (typeof req.query.header !== 'undefined' && req.query.header !== null) {
config.header.text = req.query.header;
}
if (typeof req.query.headerBackground !== 'undefined' && req.query.headerBackground !== null) {
config.header.background = req.query.headerBackground;
}
console.log('webssh2 Login: user=' + config.user.name + ' from=' + req.ip + ' host=' + config.ssh.host + ' port=' + config.ssh.port + ' sessionID=' + req.headers.sessionid + ' allowreplay=' + req.headers.allowreplay);
console.log('Headers: ' + JSON.stringify(req.headers));
config.options.allowreplay = req.headers.allowreplay;
}).use('/style', express.static(__dirname + '/public')).use('/src', express.static(__dirname + '/node_modules/xterm/dist')).use('/addons', express.static(__dirname + '/node_modules/xterm/dist/addons'));
app.use(express.static(path.join(__dirname, 'public'))).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 if (myAuth.name === '') {
res.statusCode = 401
res.setHeader('WWW-Authenticate', 'Basic realm="WebSSH"')
res.end('Username and password required for web SSH service.')
} else {
config.user.name = myAuth.name
config.user.password = myAuth.pass
next()
}
}).use(cookieParser()).get('/ssh/host/:host?', function (req, res) {
res.sendFile(path.join(path.join(__dirname, 'public', 'client.htm')))
config.ssh.host = req.params.host
if (typeof req.query.port !== 'undefined' && req.query.port !== null) {
config.ssh.port = req.query.port
}
if (typeof req.query.header !== 'undefined' && req.query.header !== null) {
config.header.text = req.query.header
}
if (typeof req.query.headerBackground !== 'undefined' && req.query.headerBackground !== null) {
config.header.background = req.query.headerBackground
}
console.log('webssh2 Login: user=' + config.user.name + ' from=' + req.ip + ' host=' + config.ssh.host + ' port=' + config.ssh.port + ' sessionID=' + req.headers.sessionid + ' allowreplay=' + req.headers.allowreplay)
console.log('Headers: ' + JSON.stringify(req.headers))
config.options.allowreplay = req.headers.allowreplay
}).use('/style', express.static(path.join(__dirname, 'public'))).use('/src', express.static(path.join(__dirname, 'node_modules', 'xterm', 'dist'))).use('/addons', express.static(path.join(__dirname, 'node_modules', 'xterm', 'dist', 'addons')))
io.on('connection', function(socket) {
var conn = new ssh();
socket.on('geometry', function(cols, rows) {
termCols = cols;
termRows = rows;
});
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");
socket.emit('data', d.toString('binary'));
}).on('ready', function() {
socket.emit('title', 'ssh://' + config.ssh.host);
socket.emit('headerBackground', config.header.background);
socket.emit('header', config.header.text);
socket.emit('footer', 'ssh://' + config.user.name + '@' + config.ssh.host + ':' + config.ssh.port);
socket.emit('status', 'SSH CONNECTION ESTABLISHED');
socket.emit('statusBackground', 'green');
socket.emit('allowreplay', config.options.allowreplay);
conn.on('banner', function (d) {
// need to convert to cr/lf for proper formatting
d = d.replace(/\r?\n/g, '\r\n')
socket.emit('data', d.toString('binary'))
}).on('ready', function () {
socket.emit('title', 'ssh://' + config.ssh.host)
socket.emit('headerBackground', config.header.background)
socket.emit('header', config.header.text)
socket.emit('footer', 'ssh://' + config.user.name + '@' + config.ssh.host + ':' + config.ssh.port)
socket.emit('status', 'SSH CONNECTION ESTABLISHED')
socket.emit('statusBackground', 'green')
socket.emit('allowreplay', config.options.allowreplay)
conn.shell({
term: config.ssh.term,
cols: termCols,
rows: termRows
}, function(err, stream) {
if (err) {
console.log(err.message);
myError = myError + err.message;
return socket.emit('status', 'SSH EXEC ERROR: ' + err.message).emit('statusBackground', 'red');
}
socket.on('data', function(data) {
stream.write(data);
});
socket.on('control', function(controlData) {
switch (controlData) {
case 'replayCredentials':
stream.write(config.user.password + '\n');
conn.shell({
term: config.ssh.term,
cols: termCols,
rows: termRows
}, function (err, stream) {
if (err) {
console.log(err.message)
myError = myError + err.message
return socket.emit('status', 'SSH EXEC ERROR: ' + err.message).emit('statusBackground', 'red')
}
socket.on('data', function (data) {
stream.write(data)
})
socket.on('control', function (controlData) {
switch (controlData) {
case 'replayCredentials':
stream.write(config.user.password + '\n')
/* falls through */
default:
console.log('controlData: ' + controlData);
}
});
stream.on('data', function(d) {
socket.emit('data', d.toString('binary'));
}).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);
});
});
}).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);
socket.emit('statusBackground', 'red');
console.log('on.error' + myError);
}).on('keyboard-interactive', function(name, instructions, instructionsLang, prompts, finish) {
console.log('Connection :: keyboard-interactive');
finish([config.user.password]);
}).connect({
host: config.ssh.host,
port: config.ssh.port,
username: config.user.name,
password: config.user.password,
tryKeyboard: true,
// 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']
default:
console.log('controlData: ' + controlData)
}
});
});
})
stream.on('data', function (d) {
socket.emit('data', d.toString('binary'))
}).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)
})
})
}).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)
socket.emit('statusBackground', 'red')
console.log('on.error' + myError)
}).on('keyboard-interactive', function (name, instructions, instructionsLang, prompts, finish) {
console.log('Connection :: keyboard-interactive')
finish([config.user.password])
}).connect({
host: config.ssh.host,
port: config.ssh.port,
username: config.user.name,
password: config.user.password,
tryKeyboard: true,
// 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']
}
})
})

View file

@ -1,117 +1,117 @@
var sessionLog,
sessionLogEnable = false,
sessionFooter,
logDate;
sessionLogEnable = false,
sessionFooter,
logDate
// replay password to server, requires
function replayCredentials() {
socket.emit('control', 'replayCredentials');
console.log("replaying credentials");
return false;
function replayCredentials () {
socket.emit('control', 'replayCredentials')
console.log('replaying credentials')
return false
}
// Set variable to toggle log data from client/server to a varialble
// for later download
function toggleLog() {
if (sessionLogEnable == true) {
sessionLogEnable = false;
document.getElementById('toggleLog').innerHTML = '<a class="toggleLog" href="javascript:void(0);" onclick="toggleLog();">Start Log</a>';
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('toggleLog').innerHTML = '<a class="toggleLog" href="javascript:void(0)" onclick="toggleLog();">Logging - STOP LOG</a>';
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 toggleLog () {
if (sessionLogEnable === true) {
sessionLogEnable = false
document.getElementById('toggleLog').innerHTML = '<a class="toggleLog" href="javascript:void(0);" onclick="toggleLog();">Start Log</a>'
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('toggleLog').innerHTML = '<a class="toggleLog" href="javascript:void(0)" onclick="toggleLog();">Logging - STOP LOG</a>'
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
}
}
// cross browser method to "download" an element to the local system
// used for our client-side logging feature
function downloadLog() {
myFile = "WebSSH2-" + logDate.getFullYear() + (logDate.getMonth() + 1) + logDate.getDate() + "_" + logDate.getHours() + logDate.getMinutes() + logDate.getSeconds() + ".log";
function downloadLog () {
myFile = 'WebSSH2-' + logDate.getFullYear() + (logDate.getMonth() + 1) + logDate.getDate() + '_' + logDate.getHours() + logDate.getMinutes() + logDate.getSeconds() + '.log'
// regex should eliminate escape sequences from being logged.
var blob = new Blob([sessionLog.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '')], {
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);
}
var blob = new Blob([sessionLog.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '')], {
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)
}
}
document.getElementById('downloadLog').style.display = 'none';
document.getElementById('credentials').style.display = 'none';
document.getElementById('downloadLog').style.display = 'none'
document.getElementById('credentials').style.display = 'none'
var terminalContainer = document.getElementById('terminal-container'),
term = new Terminal({
cursorBlink: true
}),
socket,
termid;
term.open(terminalContainer);
term.fit();
term = new Terminal({
cursorBlink: true
}),
socket,
termid
term.open(terminalContainer)
term.fit()
if (document.location.pathname) {
var parts = document.location.pathname.split('/'),
base = parts.slice(0, parts.length - 1).join('/') + '/',
resource = base.substring(1) + 'socket.io';
socket = io.connect(null, {
resource: resource
});
var parts = document.location.pathname.split('/'),
base = parts.slice(0, parts.length - 1).join('/') + '/',
resource = base.substring(1) + 'socket.io'
socket = io.connect(null, {
resource: resource
})
} else {
socket = io.connect();
socket = io.connect()
}
socket.on('connect', function() {
socket.emit('geometry', term.cols, term.rows);
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) {
sessionFooter = data;
document.getElementById('footer').innerHTML = data;
}).on('statusBackground', function(data) {
document.getElementById('status').style.backgroundColor = data;
}).on('allowreplay', function(data) {
if (data == 'true') {
console.log('allowreplay: ' + data);
document.getElementById('credentials').style.display = 'inline';
} else {
document.getElementById('credentials').style.display = 'none';
}
}).on('data', function(data) {
term.write(data);
if (sessionLogEnable) {
sessionLog = sessionLog + data
}
}).on('disconnect', function(err) {
document.getElementById('status').style.backgroundColor = 'red';
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;
});
});
socket.on('connect', function () {
socket.emit('geometry', term.cols, term.rows)
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) {
sessionFooter = data
document.getElementById('footer').innerHTML = data
}).on('statusBackground', function (data) {
document.getElementById('status').style.backgroundColor = data
}).on('allowreplay', function (data) {
if (data === 'true') {
console.log('allowreplay: ' + data)
document.getElementById('credentials').style.display = 'inline'
} else {
document.getElementById('credentials').style.display = 'none'
}
}).on('data', function (data) {
term.write(data)
if (sessionLogEnable) {
sessionLog = sessionLog + data
}
}).on('disconnect', function (err) {
document.getElementById('status').style.backgroundColor = 'red'
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
})
})