refactoring, socket.io update
more refactoring, code standards, updated socket.io to 1.7.4, increment release to 0.1.1
This commit is contained in:
parent
9dace2501c
commit
7cbfed20e9
21 changed files with 286 additions and 211 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,6 +3,9 @@ logs
|
|||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Editor preference files
|
||||
*.sublime-*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
|
|
20
ChangeLog.md
20
ChangeLog.md
|
@ -1,4 +1,18 @@
|
|||
# Change Log
|
||||
## [0.1.1] 2017-06-03
|
||||
### Added
|
||||
- `serverlog.client` and `serverlog.server` options added to `config.json` to enable logging of client commands to server log (only client portion implemented at this time)
|
||||
- morgan express middleware for logging
|
||||
### Changed
|
||||
- Updated socket.io to 1.7.4
|
||||
- continued refactoring, breaking up `index.js`
|
||||
- revised error handling methods
|
||||
- revised session termination methods
|
||||
### Fixed
|
||||
### Removed
|
||||
- color console decorations from `util/index.js`
|
||||
- SanatizeHeaders function from `util/index.js`
|
||||
|
||||
## [0.1.0] 2017-05-27
|
||||
### Added
|
||||
- This ChangeLog.md file
|
||||
|
@ -6,7 +20,7 @@
|
|||
- Snyk, Bithound, Travis CI
|
||||
- Cross platform improvements (path mappings)
|
||||
- Session fixup between Express and Socket.io
|
||||
- Session secret settings in config.json
|
||||
- Session secret settings in `config.json`
|
||||
- env variable `DEBUG=ssh2` will put the `ssh2` module into debug mode
|
||||
- env variable `DEBUG=WebSSH2` will output additional debug messages for functions
|
||||
and events in the application (not including the ssh2 module debug)
|
||||
|
@ -19,7 +33,7 @@ and events in the application (not including the ssh2 module debug)
|
|||
- error handling in public/client.js
|
||||
- moved socket.io operations to their own file /socket/index.js, more changes like this to come (./socket/index.js)
|
||||
- all session based variables are now under the req.session.ssh property or socket.request.ssh (./index.js)
|
||||
- moved SSH algorithms to config.json and defined as a session variable (..session.ssh.algorithms)
|
||||
- moved SSH algorithms to `config.json` and defined as a session variable (..session.ssh.algorithms)
|
||||
-- prep for future feature to define algorithms in header or some other method to enable separate ciphers per host
|
||||
- minified and combined all js files to a single js in `./public/webssh2.min.js` also included a sourcemap `./public/webssh2.min.js` which maps to `./public/webssh2.js` for easier troubleshooting.
|
||||
- combined all css files to a single css in `./public/webssh2.css`
|
||||
|
@ -28,7 +42,7 @@ and events in the application (not including the ssh2 module debug)
|
|||
- sourcemaps of all minified code (in /public/src and /public/src/js)
|
||||
- renamed `client.htm` to `client-full.htm`
|
||||
- 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.
|
||||
- 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
|
||||
- Multiple errors may overwrite 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.
|
||||
|
|
13
README.md
13
README.md
|
@ -1,7 +1,7 @@
|
|||
# WebSSH2 [](https://badge.fury.io/gh/billchurch%2FWebSSH2) [](https://travis-ci.org/billchurch/WebSSH2) [](https://snyk.io/test/github/billchurch/webssh2) [](https://www.bithound.io/github/billchurch/WebSSH2) [](https://www.bithound.io/github/billchurch/WebSSH2/master/dependencies/npm) [](https://nodesecurity.io/orgs/billchurch/projects/b0a0d9df-1340-43ef-9736-ef983c057764)
|
||||
Web SSH Client using ssh2, socket.io, xterm.js, and express
|
||||
|
||||
Bare bones example of using SSH2 as a client on a host to proxy a Websocket / Socket.io connection to a SSH2 server.
|
||||
Bare bones example of using SSH2 as a client on a host to proxy a Websocket / Socket.io connection to a SSH2 server.
|
||||
|
||||
<img width="1044" alt="Screenshot 2017-03-23 18.13.59" src="https://cloud.githubusercontent.com/assets/1668075/24272639/8ad4fef0-0ff4-11e7-8dd0-72b26605e467.png">
|
||||
|
||||
|
@ -29,7 +29,7 @@ You will be prompted for credentials to use on the SSH server via HTTP Basic aut
|
|||
|
||||
* **header=** - _string_ - optional header to display on page
|
||||
|
||||
* **headerBackground=** - _string_ - optional background color of header to display on page
|
||||
* **headerBackground=** - _string_ - optional background color of header to display on page
|
||||
|
||||
## Headers
|
||||
|
||||
|
@ -62,7 +62,7 @@ You will be prompted for credentials to use on the SSH server via HTTP Basic aut
|
|||
|
||||
* **session.secret** - _string_ - Secret key for cookie encryption. You should change this in production.
|
||||
|
||||
* **options.challengeButton** - _boolean_ - Challenge button. This option, which is still under development, allows the user to resend the password to the server (in cases of step-up authentication for things like `sudo` or a router `enable` command.
|
||||
* **options.challengeButton** - _boolean_ - Challenge button. This option, which is still under development, allows the user to resend the password to the server (in cases of step-up authentication for things like `sudo` or a router `enable` command.
|
||||
|
||||
* **algorithms** - _object_ - This option allows you to explicitly override the default transport layer algorithms used for the connection. Each value must be an array of valid algorithms for that category. The order of the algorithms in the arrays are important, with the most favorable being first. Valid keys:
|
||||
|
||||
|
@ -152,6 +152,11 @@ You will be prompted for credentials to use on the SSH server via HTTP Basic aut
|
|||
* zlib@openssh.com
|
||||
* zlib
|
||||
|
||||
* **serverlog.client** - _boolean_ - Enables client command logging on server log (console.log). Very simple at this point, buffers data from client until it receives a line-feed then dumps buffer to console.log with session information for tracking. Will capture anything send from client, including passwords, so use for testing only... Default: false. Example:
|
||||
* _serverlog.client: GcZDThwA4UahDiKO2gkMYd7YPIfVAEFW/mnf0NUugLMFRHhsWAAAA host: 192.168.99.80 command: ls -lat_
|
||||
|
||||
* **serverlog.server** - _boolean_ - not implemented, default: false.
|
||||
|
||||
# Experimental client-side logging
|
||||
Clicking `Start logging` on the status bar will log all data to the client. A `Download log` option will appear after starting the logging. You may download at any time to the client. You may stop logging at any time my pressing the `Logging - STOP LOG`. Note that clicking the `Start logging` option again will cause the current log to be overwritten, so be sure to download first.
|
||||
|
||||
|
@ -162,4 +167,4 @@ http://localhost:2222/ssh/host/192.168.1.1?port=2244&header=My%20Header&color=re
|
|||
# Tips
|
||||
* If you want to add custom JavaScript to the browser client you can either modify `./public/client-(full|min).html` and add a **<script>** element or check out `Gulpfile.js` and add your custom javascript file to the concat task
|
||||
* BIG-IP Acess Policy Manager (APM) doesn't always care for minified javascript when run in portal mode. Be sure to Set `useminified` option in `config.json` to `false` for these environments
|
||||
* Set `useminified` option in `config.json` to `true` to utilize minified javascript
|
||||
* Set `useminified` option in `config.json` to `true` to utilize minified javascript
|
||||
|
|
80
app.js
Normal file
80
app.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
// app.js
|
||||
|
||||
var path = require('path')
|
||||
var config = require('read-config')(path.join(__dirname, 'config.json'))
|
||||
var express = require('express')
|
||||
var logger = require('morgan')
|
||||
var session = require('express-session')({
|
||||
secret: config.session.secret,
|
||||
name: config.session.name,
|
||||
resave: true,
|
||||
saveUninitialized: false,
|
||||
unset: 'destroy'
|
||||
})
|
||||
var app = express()
|
||||
var server = require('http').Server(app)
|
||||
var myutil = require('./util')
|
||||
var validator = require('validator')
|
||||
var io = require('socket.io')(server, { serveClient: false })
|
||||
var socket = require('./socket')
|
||||
var expressOptions = require('./expressOptions')
|
||||
|
||||
// express
|
||||
app.use(session)
|
||||
app.use(myutil.basicAuth)
|
||||
if (config.accesslog) app.use(logger('common'))
|
||||
app.disable('x-powered-by')
|
||||
|
||||
// static files
|
||||
app.use(express.static(path.join(__dirname, 'public'), expressOptions))
|
||||
|
||||
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')))
|
||||
// capture, assign, and validated variables
|
||||
req.session.ssh = {
|
||||
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: (validator.isInt(req.query.port + '', {min: 1, max: 65535}) &&
|
||||
req.query.port) || config.ssh.port,
|
||||
header: {
|
||||
name: req.query.header || config.header.text,
|
||||
background: req.query.headerBackground || config.header.background
|
||||
},
|
||||
algorithms: config.algorithms,
|
||||
term: (/^(([a-z]|[A-Z]|[0-9]|[!^(){}\-_~])+)?\w$/.test(req.query.sshterm) &&
|
||||
req.query.sshterm) || config.ssh.term,
|
||||
allowreplay: validator.isBoolean(req.headers.allowreplay + '') || false,
|
||||
serverlog: {
|
||||
client: config.serverlog.client || false,
|
||||
server: config.serverlog.server || 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)
|
||||
})
|
||||
|
||||
// express error handling
|
||||
app.use(function (req, res, next) {
|
||||
res.status(404).send("Sorry can't find that!")
|
||||
})
|
||||
|
||||
app.use(function (err, req, res, next) {
|
||||
console.error(err.stack)
|
||||
res.status(500).send('Something broke!')
|
||||
})
|
||||
|
||||
// socket.io
|
||||
// expose express session with socket.request.session
|
||||
io.use(function (socket, next) {
|
||||
(socket.request.res) ? session(socket.request, socket.request.res, next)
|
||||
: next()
|
||||
})
|
||||
|
||||
// bring up socket
|
||||
io.on('connection', socket)
|
||||
|
||||
module.exports = {server: server, config: config}
|
|
@ -52,5 +52,10 @@
|
|||
"zlib@openssh.com",
|
||||
"zlib"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serverlog": {
|
||||
"client": false, // proof-of-concept to log commands from client to server
|
||||
"server": false // not yet implemented
|
||||
},
|
||||
"accesslog": false // http style access logging to console.log
|
||||
}
|
||||
|
|
11
expressOptions.js
Normal file
11
expressOptions.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
module.exports = {
|
||||
dotfiles: 'ignore',
|
||||
etag: false,
|
||||
extensions: ['htm', 'html'],
|
||||
index: false,
|
||||
maxAge: '1s',
|
||||
redirect: false,
|
||||
setHeaders: function (res, path, stat) {
|
||||
res.set('x-timestamp', Date.now())
|
||||
}
|
||||
}
|
85
index.js
85
index.js
|
@ -1,97 +1,24 @@
|
|||
// server.js
|
||||
/*
|
||||
* WebSSH2 - Web to SSH2 gateway
|
||||
* Bill Church - https://github.com/billchurch/WebSSH2 - May 2017
|
||||
*
|
||||
*/
|
||||
var express = require('express')
|
||||
var app = express()
|
||||
var server = require('http').Server(app)
|
||||
var io = require('socket.io')(server)
|
||||
var path = require('path')
|
||||
var config = require('read-config')(path.join(__dirname, 'config.json'))
|
||||
var myutil = require('./util')
|
||||
var socket = require('./socket/index.js')
|
||||
var validator = require('validator')
|
||||
var session = require('express-session')({
|
||||
secret: config.session.secret,
|
||||
name: config.session.name,
|
||||
resave: true,
|
||||
saveUninitialized: false,
|
||||
unset: 'destroy'
|
||||
})
|
||||
|
||||
// express
|
||||
var expressOptions = {
|
||||
dotfiles: 'ignore',
|
||||
etag: false,
|
||||
extensions: ['htm', 'html'],
|
||||
index: false,
|
||||
maxAge: '1s',
|
||||
redirect: false,
|
||||
setHeaders: function (res, path, stat) {
|
||||
res.set('x-timestamp', Date.now())
|
||||
}
|
||||
}
|
||||
var config = require('./app').config
|
||||
var server = require('./app').server
|
||||
|
||||
app.use(session)
|
||||
app.use(myutil.basicAuth)
|
||||
|
||||
app.disable('x-powered-by')
|
||||
|
||||
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')))
|
||||
// capture and assign variables
|
||||
req.session.ssh = {
|
||||
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: (validator.isInt(req.query.port + '', {min: 1, max: 65535}) && req.query.port) || config.ssh.port,
|
||||
header: {
|
||||
name: req.query.header || config.header.text,
|
||||
background: req.query.headerBackground || config.header.background
|
||||
},
|
||||
algorithms: config.algorithms,
|
||||
term: (/^(([a-z]|[A-Z]|[0-9]|[!^(){}\-_~])+)?\w$/.test(req.query.sshterm) && req.query.sshterm) || config.ssh.term,
|
||||
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
|
||||
app.use(express.static(path.join(__dirname, 'public'), expressOptions))
|
||||
|
||||
// express error handling
|
||||
app.use(function (req, res, next) {
|
||||
res.status(404).send("Sorry can't find that!")
|
||||
})
|
||||
|
||||
app.use(function (err, req, res, next) {
|
||||
console.error(err.stack)
|
||||
res.status(500).send('Something broke!')
|
||||
})
|
||||
|
||||
// socket.io
|
||||
// expose express session with socket.request.session
|
||||
io.use(function (socket, next) {
|
||||
(socket.request.res) ? session(socket.request, socket.request.res, next) : next()
|
||||
})
|
||||
|
||||
// bring up socket
|
||||
io.on('connection', socket)
|
||||
|
||||
// server
|
||||
server.listen({
|
||||
host: config.listen.ip,
|
||||
port: config.listen.port
|
||||
server.listen({ host: config.listen.ip, port: config.listen.port
|
||||
})
|
||||
|
||||
server.on('error', function (err) {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
config.listen.port++
|
||||
console.warn('Address in use, retrying on port ' + config.listen.port)
|
||||
console.warn('WebSSH2 Address in use, retrying on port ' + config.listen.port)
|
||||
setTimeout(function () {
|
||||
server.listen(config.listen.port)
|
||||
}, 250)
|
||||
} else {
|
||||
console.log('server.listen ERROR: ' + err.code)
|
||||
console.log('WebSSH2 server.listen ERROR: ' + err.code)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "WebSSH2",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"ignore": [
|
||||
".gitignore"
|
||||
],
|
||||
|
@ -32,8 +32,9 @@
|
|||
"debug": "^2.6.8",
|
||||
"express": "^4.15.3",
|
||||
"express-session": "^1.15.3",
|
||||
"morgan": "^1.8.2",
|
||||
"read-config": "^1.6.0",
|
||||
"socket.io": "^1.6.0",
|
||||
"socket.io": "^1.7.4",
|
||||
"ssh2": "^0.5.4",
|
||||
"validator": "^7.0.0"
|
||||
},
|
||||
|
|
|
@ -11,9 +11,12 @@
|
|||
<div id="bottomdiv">
|
||||
<div id="footer"></div>
|
||||
<div id="status"></div>
|
||||
<div id="credentials"><a class="credentials" href="javascript:void(0);" onclick="replayCredentials()">CREDENTIALS</a></div>
|
||||
<div id="downloadLog"><a class="downloadLog" href="javascript:void(0);" onclick="downloadLog()">Download Log</a></div>
|
||||
<div id="toggleLog"><a class="toggleLog" href="javascript:void(0);" onclick="toggleLog();">Start Log</a></div>
|
||||
<div id="credentials"><a class="credentials" href="javascript:void(0);"
|
||||
onclick="replayCredentials()">CREDENTIALS</a></div>
|
||||
<div id="downloadLog"><a class="downloadLog" href="javascript:void(0);"
|
||||
onclick="downloadLog()">Download Log</a></div>
|
||||
<div id="toggleLog"><a class="toggleLog" href="javascript:void(0);"
|
||||
onclick="toggleLog();">Start Log</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -11,9 +11,12 @@
|
|||
<div id="bottomdiv">
|
||||
<div id="footer"></div>
|
||||
<div id="status"></div>
|
||||
<div id="credentials"><a class="credentials" href="javascript:void(0);" onclick="replayCredentials()">CREDENTIALS</a></div>
|
||||
<div id="downloadLog"><a class="downloadLog" href="javascript:void(0);" onclick="downloadLog()">Download Log</a></div>
|
||||
<div id="toggleLog"><a class="toggleLog" href="javascript:void(0);" onclick="toggleLog();">Start Log</a></div>
|
||||
<div id="credentials"><a class="credentials" href="javascript:void(0);"
|
||||
onclick="replayCredentials()">CREDENTIALS</a></div>
|
||||
<div id="downloadLog"><a class="downloadLog" href="javascript:void(0);"
|
||||
onclick="downloadLog()">Download Log</a></div>
|
||||
<div id="toggleLog"><a class="toggleLog" href="javascript:void(0);"
|
||||
onclick="toggleLog();">Start Log</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -88,7 +88,7 @@ body {
|
|||
}
|
||||
a.credentials {
|
||||
color: rgb(51, 51, 51);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
#downloadLog {
|
||||
display: inline-block;
|
||||
|
@ -104,7 +104,7 @@ a.credentials {
|
|||
}
|
||||
a.downloadLog {
|
||||
color: rgb(240, 240, 240);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
#toggleLog {
|
||||
display: inline-block;
|
||||
|
@ -120,5 +120,5 @@ a.downloadLog {
|
|||
}
|
||||
a.toggleLog {
|
||||
color: rgb(240, 240, 240);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
|
|
@ -14,19 +14,27 @@ function replayCredentials () { // eslint-disable-line
|
|||
function toggleLog () { // eslint-disable-line
|
||||
if (sessionLogEnable === true) {
|
||||
sessionLogEnable = false
|
||||
document.getElementById('toggleLog').innerHTML = '<a class="toggleLog" href="javascript:void(0);" onclick="toggleLog();">Start Log</a>'
|
||||
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'
|
||||
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('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'
|
||||
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
|
||||
}
|
||||
|
@ -35,7 +43,9 @@ function toggleLog () { // eslint-disable-line
|
|||
// cross browser method to "download" an element to the local system
|
||||
// used for our client-side logging feature
|
||||
function downloadLog () { // eslint-disable-line
|
||||
myFile = 'WebSSH2-' + logDate.getFullYear() + (logDate.getMonth() + 1) + logDate.getDate() + '_' + logDate.getHours() + logDate.getMinutes() + logDate.getSeconds() + '.log'
|
||||
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'
|
||||
|
@ -113,7 +123,8 @@ socket.on('connect', function () {
|
|||
}).on('disconnect', function (err) {
|
||||
if (!errorExists) {
|
||||
document.getElementById('status').style.backgroundColor = 'red'
|
||||
document.getElementById('status').innerHTML = 'WEBSOCKET SERVER DISCONNECTED: ' + err
|
||||
document.getElementById('status').innerHTML =
|
||||
'WEBSOCKET SERVER DISCONNECTED: ' + err
|
||||
}
|
||||
socket.io.reconnection(false)
|
||||
}).on('error', function (err) {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -88,7 +88,7 @@ body {
|
|||
}
|
||||
a.credentials {
|
||||
color: rgb(51, 51, 51);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
#downloadLog {
|
||||
display: inline-block;
|
||||
|
@ -104,7 +104,7 @@ a.credentials {
|
|||
}
|
||||
a.downloadLog {
|
||||
color: rgb(240, 240, 240);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
#toggleLog {
|
||||
display: inline-block;
|
||||
|
@ -120,7 +120,7 @@ a.downloadLog {
|
|||
}
|
||||
a.toggleLog {
|
||||
color: rgb(240, 240, 240);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12520,19 +12520,27 @@ function replayCredentials () { // eslint-disable-line
|
|||
function toggleLog () { // eslint-disable-line
|
||||
if (sessionLogEnable === true) {
|
||||
sessionLogEnable = false
|
||||
document.getElementById('toggleLog').innerHTML = '<a class="toggleLog" href="javascript:void(0);" onclick="toggleLog();">Start Log</a>'
|
||||
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'
|
||||
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('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'
|
||||
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
|
||||
}
|
||||
|
@ -12541,7 +12549,9 @@ function toggleLog () { // eslint-disable-line
|
|||
// cross browser method to "download" an element to the local system
|
||||
// used for our client-side logging feature
|
||||
function downloadLog () { // eslint-disable-line
|
||||
myFile = 'WebSSH2-' + logDate.getFullYear() + (logDate.getMonth() + 1) + logDate.getDate() + '_' + logDate.getHours() + logDate.getMinutes() + logDate.getSeconds() + '.log'
|
||||
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'
|
||||
|
@ -12619,7 +12629,8 @@ socket.on('connect', function () {
|
|||
}).on('disconnect', function (err) {
|
||||
if (!errorExists) {
|
||||
document.getElementById('status').style.backgroundColor = 'red'
|
||||
document.getElementById('status').innerHTML = 'WEBSOCKET SERVER DISCONNECTED: ' + err
|
||||
document.getElementById('status').innerHTML =
|
||||
'WEBSOCKET SERVER DISCONNECTED: ' + err
|
||||
}
|
||||
socket.io.reconnection(false)
|
||||
}).on('error', function (err) {
|
||||
|
|
2
public/webssh2.min.js
vendored
2
public/webssh2.min.js
vendored
File diff suppressed because one or more lines are too long
131
socket/index.js
131
socket/index.js
|
@ -1,3 +1,5 @@
|
|||
// socket/index.js
|
||||
|
||||
// private
|
||||
var debug = require('debug')
|
||||
var debugWebSSH2 = require('debug')('WebSSH2')
|
||||
|
@ -5,30 +7,7 @@ var SSH = require('ssh2').Client
|
|||
var termCols, termRows
|
||||
|
||||
// public
|
||||
module.exports = function (socket) {
|
||||
function SSHerror (myFunc, err) {
|
||||
socket.request.session.error = (socket.request.session.error) || ((err) ? err.message : undefined)
|
||||
var theError = (socket.request.session.error) ? ': ' + socket.request.session.error : ''
|
||||
// log unsuccessful login attempt
|
||||
if (err && (err.level === 'client-authentication')) {
|
||||
console.log('webssh2 ' + 'error: Authentication failure'.red.bold +
|
||||
' user=' + socket.request.session.username.yellow.bold.underline +
|
||||
' from=' + socket.handshake.address.yellow.bold.underline)
|
||||
}
|
||||
switch (myFunc) {
|
||||
case 'STREAM CLOSE':
|
||||
debugWebSSH2('SSH ' + myFunc + theError.red)
|
||||
socket.emit('ssherror', 'SSH ' + myFunc + theError)
|
||||
socket.disconnect(true)
|
||||
break
|
||||
default:
|
||||
debugWebSSH2('SSHerror: default'.red)
|
||||
debugWebSSH2('SSH ' + myFunc + theError)
|
||||
socket.emit('ssherror', 'SSH ' + myFunc + theError)
|
||||
socket.disconnect(true)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function socket (socket) {
|
||||
// if websocket connection arrives without an express session, kill it
|
||||
if (!socket.request.session) {
|
||||
socket.emit('401 UNAUTHORIZED')
|
||||
|
@ -37,19 +16,18 @@ module.exports = function (socket) {
|
|||
return
|
||||
}
|
||||
var conn = new SSH()
|
||||
socket.on('geometry', function (cols, rows) {
|
||||
socket.on('geometry', function socketOnGeometry (cols, rows) {
|
||||
termCols = cols
|
||||
termRows = rows
|
||||
})
|
||||
console.log('webssh2 ' + 'IO ON:'.cyan.bold + ' 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)
|
||||
conn.on('banner', function (d) {
|
||||
conn.on('banner', function connOnBanner (data) {
|
||||
// need to convert to cr/lf for proper formatting
|
||||
d = d.replace(/\r?\n/g, '\r\n')
|
||||
socket.emit('data', d.toString('binary'))
|
||||
data = data.replace(/\r?\n/g, '\r\n')
|
||||
socket.emit('data', data.toString('utf-8'))
|
||||
})
|
||||
|
||||
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)
|
||||
conn.on('ready', function connOnReady () {
|
||||
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.request.session.ssh.header.background && socket.emit('headerBackground', socket.request.session.ssh.header.background)
|
||||
socket.request.session.ssh.header.name && socket.emit('header', socket.request.session.ssh.header.name)
|
||||
|
@ -61,25 +39,27 @@ module.exports = function (socket) {
|
|||
term: socket.request.session.ssh.term,
|
||||
cols: termCols,
|
||||
rows: termRows
|
||||
}, function (err, stream) {
|
||||
}, function connShell (err, stream) {
|
||||
if (err) {
|
||||
SSHerror('EXEC ERROR' + err)
|
||||
conn.end()
|
||||
return
|
||||
}
|
||||
// poc to log commands from client
|
||||
// var dataBuffer
|
||||
socket.on('data', function (data) {
|
||||
if (socket.request.session.ssh.serverlog.client) var dataBuffer
|
||||
socket.on('data', function socketOnData (data) {
|
||||
stream.write(data)
|
||||
// poc to log commands from client
|
||||
// if (data === '\r') {
|
||||
// console.log(socket.request.session.id + '/' + socket.id + ' command: ' + socket.request.session.ssh.host + ': ' + dataBuffer)
|
||||
// dataBuffer = undefined
|
||||
// } else {
|
||||
// dataBuffer = (dataBuffer) ? dataBuffer + data : data
|
||||
// }
|
||||
if (socket.request.session.ssh.serverlog.client) {
|
||||
if (data === '\r') {
|
||||
console.log('serverlog.client: ' + socket.request.session.id + '/' + socket.id + ' host: ' + socket.request.session.ssh.host + ' command: ' + dataBuffer)
|
||||
dataBuffer = undefined
|
||||
} else {
|
||||
dataBuffer = (dataBuffer) ? dataBuffer + data : data
|
||||
}
|
||||
}
|
||||
})
|
||||
socket.on('control', function (controlData) {
|
||||
socket.on('control', function socketOnControl (controlData) {
|
||||
switch (controlData) {
|
||||
case 'replayCredentials':
|
||||
stream.write(socket.request.session.userpassword + '\n')
|
||||
|
@ -88,55 +68,82 @@ module.exports = function (socket) {
|
|||
console.log('controlData: ' + controlData)
|
||||
}
|
||||
})
|
||||
|
||||
socket.on('disconnecting', function (reason) { debugWebSSH2('SOCKET DISCONNECTING: ' + reason) })
|
||||
|
||||
socket.on('disconnect', function (reason) {
|
||||
socket.on('disconnecting', function socketOnDisconnecting (reason) { debugWebSSH2('SOCKET DISCONNECTING: ' + reason) })
|
||||
socket.on('disconnect', function socketOnDisconnect (reason) {
|
||||
debugWebSSH2('SOCKET DISCONNECT: ' + reason)
|
||||
err = { message: reason }
|
||||
SSHerror('CLIENT SOCKET DISCONNECT', err)
|
||||
conn.end()
|
||||
// socket.request.session.destroy()
|
||||
})
|
||||
socket.on('error', function socketOnError (err) {
|
||||
SSHerror('SOCKET ERROR', err)
|
||||
conn.end()
|
||||
})
|
||||
|
||||
socket.on('error', function (error) { debugWebSSH2('SOCKET ERROR: ' + JSON.stringify(error)) })
|
||||
|
||||
stream.on('data', function (d) { socket.emit('data', d.toString('utf-8')) })
|
||||
|
||||
stream.on('close', function (code, signal) {
|
||||
stream.on('data', function streamOnData (data) { socket.emit('data', data.toString('utf-8')) })
|
||||
stream.on('close', function streamOnClose (code, signal) {
|
||||
err = { message: ((code || signal) ? (((code) ? 'CODE: ' + code : '') + ((code && signal) ? ' ' : '') + ((signal) ? 'SIGNAL: ' + signal : '')) : undefined) }
|
||||
SSHerror('STREAM CLOSE', err)
|
||||
conn.end()
|
||||
})
|
||||
|
||||
stream.stderr.on('data', function (data) {
|
||||
stream.stderr.on('data', function streamStderrOnData (data) {
|
||||
console.log('STDERR: ' + data)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
conn.on('end', function (err) { SSHerror('CONN END BY HOST', err) })
|
||||
conn.on('close', function (err) { SSHerror('CONN CLOSE', err) })
|
||||
conn.on('error', function (err) { SSHerror('CONN ERROR', err) })
|
||||
|
||||
conn.on('keyboard-interactive', function (name, instructions, instructionsLang, prompts, finish) {
|
||||
conn.on('end', function connOnEnd (err) { SSHerror('CONN END BY HOST', err) })
|
||||
conn.on('close', function connOnClose (err) { SSHerror('CONN CLOSE', err) })
|
||||
conn.on('error', function connOnError (err) { SSHerror('CONN ERROR', err) })
|
||||
conn.on('keyboard-interactive', function connOnKeyboardInteractive (name, instructions, instructionsLang, prompts, finish) {
|
||||
debugWebSSH2('conn.on(\'keyboard-interactive\')')
|
||||
finish([socket.request.session.userpassword])
|
||||
})
|
||||
if (socket.request.session.username && socket.request.session.userpassword) {
|
||||
if (socket.request.session.username && socket.request.session.userpassword && socket.request.session.ssh) {
|
||||
conn.connect({
|
||||
host: socket.request.session.ssh.host,
|
||||
port: socket.request.session.ssh.port,
|
||||
username: socket.request.session.username,
|
||||
password: socket.request.session.userpassword,
|
||||
tryKeyboard: true,
|
||||
// some cisco routers need the these cipher strings
|
||||
algorithms: socket.request.session.ssh.algorithms,
|
||||
debug: debug('ssh2')
|
||||
})
|
||||
} else {
|
||||
console.warn('Attempt to connect without session.username/password defined, potentially previously abandoned client session. disconnecting websocket client.\r\nHandshake information: \r\n ' + JSON.stringify(socket.handshake))
|
||||
socket.emit('statusBackground', 'red')
|
||||
socket.emit('status', 'WEBSOCKET ERROR - Reload and try again')
|
||||
debugWebSSH2('Attempt to connect without session.username/password or session varialbles defined, potentially previously abandoned client session. disconnecting websocket client.\r\nHandshake information: \r\n ' + JSON.stringify(socket.handshake))
|
||||
socket.emit('ssherror', 'WEBSOCKET ERROR - Refresh the browser and try again')
|
||||
socket.request.session.destroy()
|
||||
socket.disconnect(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handling for various events. Outputs error to client, logs to
|
||||
* server, destroys session and disconnects socket.
|
||||
* @param {string} myFunc Function calling this function
|
||||
* @param {object} err error object or error message
|
||||
*/
|
||||
function SSHerror (myFunc, err) {
|
||||
var theError
|
||||
if (socket.request.session) {
|
||||
// we just want the first error of the session to pass to the client
|
||||
socket.request.session.error = (socket.request.session.error) || ((err) ? err.message : undefined)
|
||||
theError = (socket.request.session.error) ? ': ' + socket.request.session.error : ''
|
||||
// log unsuccessful login attempt
|
||||
if (err && (err.level === 'client-authentication')) {
|
||||
console.log('WebSSH2 ' + 'error: Authentication failure'.red.bold +
|
||||
' user=' + socket.request.session.username.yellow.bold.underline +
|
||||
' from=' + socket.handshake.address.yellow.bold.underline)
|
||||
} else {
|
||||
console.log('WebSSH2 Logout: 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('ssherror', 'SSH ' + myFunc + theError)
|
||||
socket.request.session.destroy()
|
||||
socket.disconnect(true)
|
||||
} else {
|
||||
theError = (err) ? ': ' + err.message : ''
|
||||
socket.disconnect(true)
|
||||
}
|
||||
debugWebSSH2('SSHerror ' + myFunc + theError)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ body {
|
|||
}
|
||||
a.credentials {
|
||||
color: rgb(51, 51, 51);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
#downloadLog {
|
||||
display: inline-block;
|
||||
|
@ -104,7 +104,7 @@ a.credentials {
|
|||
}
|
||||
a.downloadLog {
|
||||
color: rgb(240, 240, 240);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
#toggleLog {
|
||||
display: inline-block;
|
||||
|
@ -120,5 +120,5 @@ a.downloadLog {
|
|||
}
|
||||
a.toggleLog {
|
||||
color: rgb(240, 240, 240);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
|
|
@ -14,19 +14,27 @@ function replayCredentials () { // eslint-disable-line
|
|||
function toggleLog () { // eslint-disable-line
|
||||
if (sessionLogEnable === true) {
|
||||
sessionLogEnable = false
|
||||
document.getElementById('toggleLog').innerHTML = '<a class="toggleLog" href="javascript:void(0);" onclick="toggleLog();">Start Log</a>'
|
||||
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'
|
||||
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('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'
|
||||
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
|
||||
}
|
||||
|
@ -35,7 +43,9 @@ function toggleLog () { // eslint-disable-line
|
|||
// cross browser method to "download" an element to the local system
|
||||
// used for our client-side logging feature
|
||||
function downloadLog () { // eslint-disable-line
|
||||
myFile = 'WebSSH2-' + logDate.getFullYear() + (logDate.getMonth() + 1) + logDate.getDate() + '_' + logDate.getHours() + logDate.getMinutes() + logDate.getSeconds() + '.log'
|
||||
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'
|
||||
|
@ -113,7 +123,8 @@ socket.on('connect', function () {
|
|||
}).on('disconnect', function (err) {
|
||||
if (!errorExists) {
|
||||
document.getElementById('status').style.backgroundColor = 'red'
|
||||
document.getElementById('status').innerHTML = 'WEBSOCKET SERVER DISCONNECTED: ' + err
|
||||
document.getElementById('status').innerHTML =
|
||||
'WEBSOCKET SERVER DISCONNECTED: ' + err
|
||||
}
|
||||
socket.io.reconnection(false)
|
||||
}).on('error', function (err) {
|
||||
|
|
|
@ -1,28 +1,18 @@
|
|||
// util/index.js
|
||||
|
||||
// private
|
||||
require('colors') // allow for color property extensions in log messages
|
||||
var debug = require('debug')('WebSSH2')
|
||||
var Auth = require('basic-auth')
|
||||
var util = require('util')
|
||||
|
||||
console.warn = makeColorConsole(console.warn, 'yellow')
|
||||
console.error = makeColorConsole(console.error, 'red')
|
||||
|
||||
// public
|
||||
function makeColorConsole (fct, color) {
|
||||
return function () {
|
||||
for (var i in arguments) {
|
||||
if (arguments[i] instanceof Object) { arguments[i] = util.inspect(arguments[i]) }
|
||||
}
|
||||
fct(Array.prototype.join.call(arguments, ' ')[color])
|
||||
}
|
||||
}
|
||||
|
||||
exports.basicAuth = function (req, res, next) {
|
||||
exports.basicAuth = function basicAuth (req, res, next) {
|
||||
var myAuth = Auth(req)
|
||||
if (myAuth) {
|
||||
req.session.username = myAuth.name
|
||||
req.session.userpassword = myAuth.pass
|
||||
debug('myAuth.name: ' + myAuth.name.yellow.bold.underline + ' and password ' + ((myAuth.pass) ? 'exists'.yellow.bold.underline : 'is blank'.underline.red.bold))
|
||||
debug('myAuth.name: ' + myAuth.name.yellow.bold.underline +
|
||||
' and password ' + ((myAuth.pass) ? 'exists'.yellow.bold.underline
|
||||
: 'is blank'.underline.red.bold))
|
||||
next()
|
||||
} else {
|
||||
res.statusCode = 401
|
||||
|
@ -31,10 +21,3 @@ exports.basicAuth = function (req, res, next) {
|
|||
res.end('Username and password required for web SSH service.')
|
||||
}
|
||||
}
|
||||
|
||||
// expects headers to be a JSON object, will replace authroization header with 'Sanatized//Exists'
|
||||
// we don't want to log basic auth header since it contains a password...
|
||||
exports.SanatizeHeaders = function (headers) {
|
||||
if (headers.authorization) { headers.authorization = 'Sanitized//Exists' }
|
||||
return (headers)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue