diff --git a/app/server/app.js b/app/server/app.js
index 5f0b490..f29ad33 100644
--- a/app/server/app.js
+++ b/app/server/app.js
@@ -3,105 +3,18 @@
// app.js
var path = require('path')
-var fs = require('fs')
var nodeRoot = path.dirname(require.main.filename)
-var configPath = path.join(nodeRoot, 'config.json')
var publicPath = path.join(nodeRoot, 'client', 'public')
-console.log('WebSSH2 service reading config from: ' + configPath)
+var config = require('./config')
var express = require('express')
var logger = require('morgan')
-
-// sane defaults if config.json or parts are missing
-let config = {
- listen: {
- ip: '0.0.0.0',
- port: 2222
- },
- user: {
- name: null,
- password: null,
- privatekey: null
- },
- ssh: {
- host: null,
- port: 22,
- term: 'xterm-color',
- readyTimeout: 20000,
- keepaliveInterval: 120000,
- keepaliveCountMax: 10,
- allowedSubnets: []
- },
- terminal: {
- cursorBlink: true,
- scrollback: 10000,
- tabStopWidth: 8,
- bellStyle: 'sound'
- },
- header: {
- text: null,
- background: 'green'
- },
- session: {
- name: 'WebSSH2',
- secret: 'mysecret'
- },
- options: {
- challengeButton: true,
- allowreauth: true
- },
- algorithms: {
- kex: [
- 'ecdh-sha2-nistp256',
- 'ecdh-sha2-nistp384',
- 'ecdh-sha2-nistp521',
- 'diffie-hellman-group-exchange-sha256',
- 'diffie-hellman-group14-sha1'
- ],
- cipher: [
- 'aes128-ctr',
- 'aes192-ctr',
- 'aes256-ctr',
- 'aes128-gcm',
- 'aes128-gcm@openssh.com',
- 'aes256-gcm',
- 'aes256-gcm@openssh.com',
- 'aes256-cbc'
- ],
- hmac: [
- 'hmac-sha2-256',
- 'hmac-sha2-512',
- 'hmac-sha1'
- ],
- compress: [
- 'none',
- 'zlib@openssh.com',
- 'zlib'
- ]
- },
- serverlog: {
- client: false,
- server: false
- },
- accesslog: false,
- verify: false
-}
-
-// test if config.json exists, if not provide error message but try to run
-// anyway
-try {
- if (fs.existsSync(configPath)) {
- console.log('ephemeral_auth service reading config from: ' + configPath)
- config = require('read-config')(configPath)
- } else {
- console.error('\n\nERROR: Missing config.json for webssh. Current config: ' + JSON.stringify(config))
- console.error('\n See config.json.sample for details\n\n')
- }
-} catch (err) {
- console.error('\n\nERROR: Missing config.json for webssh. Current config: ' + JSON.stringify(config))
- console.error('\n See config.json.sample for details\n\n')
- console.error('ERROR:\n\n ' + err)
-}
-
+var app = express()
+var compression = require('compression')
+var server = require('http').Server(app)
+var myutil = require('./util')
+var io = require('socket.io')(server, { serveClient: false })
+var socket = require('./socket')
+var expressOptions = require('./expressOptions')
var session = require('express-session')({
secret: config.session.secret,
name: config.session.name,
@@ -109,15 +22,6 @@ var session = require('express-session')({
saveUninitialized: false,
unset: 'destroy'
})
-var app = express()
-var compression = require('compression')
-var server = require('http').Server(app)
-var myutil = require('./util')
-myutil.setDefaultCredentials(config.user.name, config.user.password, config.user.privatekey);
-var validator = require('validator')
-var io = require('socket.io')(server, { serveClient: false })
-var socket = require('./socket')
-var expressOptions = require('./expressOptions')
// express
app.use(compression({ level: 9 }))
@@ -137,44 +41,6 @@ app.get('/reauth', function (req, res, next) {
// eslint-disable-next-line complexity
app.get('/ssh/host/:host?', function (req, res, next) {
res.sendFile(path.join(path.join(publicPath, 'client.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,
- localAddress: config.ssh.localAddress,
- localPort: config.ssh.localPort,
- header: {
- name: req.query.header || config.header.text,
- background: req.query.headerBackground || config.header.background
- },
- algorithms: config.algorithms,
- keepaliveInterval: config.ssh.keepaliveInterval,
- keepaliveCountMax: config.ssh.keepaliveCountMax,
- allowedSubnets: config.ssh.allowedSubnets,
- term: (/^(([a-z]|[A-Z]|[0-9]|[!^(){}\-_~])+)?\w$/.test(req.query.sshterm) &&
- req.query.sshterm) || config.ssh.term,
- terminal: {
- cursorBlink: (validator.isBoolean(req.query.cursorBlink + '') ? myutil.parseBool(req.query.cursorBlink) : config.terminal.cursorBlink),
- scrollback: (validator.isInt(req.query.scrollback + '', { min: 1, max: 200000 }) && req.query.scrollback) ? req.query.scrollback : config.terminal.scrollback,
- 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
- },
- 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'),
- serverlog: {
- client: config.serverlog.client || false,
- server: config.serverlog.server || false
- },
- readyTimeout: (validator.isInt(req.query.readyTimeout + '', { min: 1, max: 300000 }) &&
- req.query.readyTimeout) || config.ssh.readyTimeout
- }
- if (req.session.ssh.header.name) validator.escape(req.session.ssh.header.name)
- if (req.session.ssh.header.background) validator.escape(req.session.ssh.header.background)
})
// express error handling
diff --git a/app/server/socket.js b/app/server/socket.js
index da880f8..b7a64a0 100644
--- a/app/server/socket.js
+++ b/app/server/socket.js
@@ -4,44 +4,214 @@
// socket.js
// private
+var config = require('./config')
+var validator = require('validator')
var debug = require('debug')
+var myutil = require('./util')
var debugWebSSH2 = require('debug')('WebSSH2')
var SSH = require('ssh2').Client
-var CIDRMatcher = require('cidr-matcher');
+var CIDRMatcher = require('cidr-matcher')
// var fs = require('fs')
// var hostkeys = JSON.parse(fs.readFileSync('./hostkeyhashes.json', 'utf8'))
var termCols, termRows
var menuData = ' Start Log' +
' Download Log'
+// return a subset of keys from an object if they exist
+function pick (obj, keys) {
+ return keys.reduce((acc, key) => {
+ if (obj[key]) {
+ acc[key] = obj[key]
+ }
+ return acc
+ }, {})
+}
+
+const baseSocketConfig = {
+ host: config.ssh.host,
+ port: config.ssh.port,
+ localAddress: config.ssh.localAddress,
+ localPort: config.ssh.localPort,
+ term: config.ssh.term,
+ readyTimeout: config.ssh.readyTimeout,
+ algorithms: config.algorithms,
+ keepaliveInterval: config.ssh.keepaliveInterval,
+ keepaliveCountMax: config.ssh.keepaliveCountMax,
+ allowedSubnets: config.ssh.allowedSubnets || [],
+ header: {
+ name: config.header.text,
+ background: config.header.background
+ },
+ terminal: {
+ cursorBlink: config.terminal.cursorBlink,
+ scrollBack: config.terminal.scrollback,
+ tabStopWidth: config.terminal.tabStopWidth,
+ bellStyle: config.terminal.bellStyle
+ },
+ serverlog: {
+ client: config.serverlog.client || false,
+ server: config.serverlog.server || false
+ }
+}
+
+function getValidatedRequestConfig (queryParams) {
+ const processedParams = {}
+ const validators = {
+ host: (host) => validator.isIP(host + '') || validator.isFQDN(host) || /^(([a-z]|[A-Z]|[0-9]|[!^(){}\-_~])+)?\w$/.test(host),
+ port: (port) => validator.isInt(port + '', { min: 1, max: 65535 }),
+ sshterm: (sshterm) => /^(([a-z]|[A-Z]|[0-9]|[!^(){}\-_~])+)?\w$/.test(sshterm),
+ cursorBlink: (cursorBlink) => validator.isBoolean(cursorBlink + ''),
+ scrollback: (scrollback) => validator.isInt(scrollback + '', { min: 1, max: 200000 }),
+ tabStopWidth: (tabStopWidth) => validator.isInt(tabStopWidth + '', { min: 1, max: 100 }),
+ bellStyle: (bellStyle) => (['sound', 'none'].indexOf(bellStyle) > -1),
+ readyTimeout: (readyTimeout) => validator.isInt(readyTimeout + '', { min: 1, max: 300000 }),
+ header: () => true,
+ headerBackground: () => true
+ }
+ const transformations = {
+ cursorBlink: (cursorBlink) => myutil.parseBool(cursorBlink)
+ }
+ const rename = {
+ sshterm: 'term'
+ }
+
+ // validate & transform and rename query parameters
+ for (const key in queryParams) {
+ const value = queryParams[key]
+ const validator = validators[key] || (() => false)
+ const transformation = transformations[key] || ((i) => i)
+ const newName = rename[key] || key
+
+ if (value !== undefined && validator(value)) {
+ processedParams[newName] = transformation(value)
+ }
+ }
+
+ // todo: address all this!!
+ // const allowreplay = config.options.challengeButton || (validator.isBoolean(req.headers.allowreplay + '') ? myutil.parseBool(req.headers.allowreplay) : false)
+ // const allowreauth = config.options.allowreauth || false
+ // const mrhsession = ((validator.isAlphanumeric(req.headers.mrhsession + '') && req.headers.mrhsession) ? req.headers.mrhsession : 'none')
+ // if (req.session.ssh.header.name) validator.escape(req.session.ssh.header.name)
+ // if (req.session.ssh.header.background) validator.escape(req.session.ssh.header.background)
+ // todo: do this when creating base config?
+ // if (socketConfig.header.name) {
+ // validator.escape(socketConfig.header.name)
+ // }
+ // if (socketConfig.header.background) {
+ // validator.escape(socketConfig.header.background)
+ // }
+
+ // create config object from query parameters
+ const config = pick(processedParams, ['host', 'port', 'readyTimeout', 'term'])
+ config.terminal = pick(processedParams, ['cursorBlink', 'scrollback', 'tabStopWidth', 'bellStyle'])
+ config.header = pick(processedParams, ['header', 'headerBackground'])
+
+ return config
+}
+
+function getCredentials (session) {
+ if (session.username && session.userpassword) {
+ return {
+ username: session.username,
+ userpassword: session.userpassword
+ }
+ } else {
+ return myutil.defaultCredentials
+ }
+}
+
+/**
+ * Error handling for various events. Outputs error to client, logs to
+ * server, destroys session and disconnects socket.
+ * @param {string} callerName Function calling this function
+ * @param {object} err Error object or error message
+ * @param {object} context Additional information about the state when the error occurred
+ * @param {object} context.socket The socket.io socket object at the time of failure
+ * @param {object} context.socketConfig The config object based on the base config and the request query parameters
+ * @param {object} context.credentials The credentials used during the connection that failed
+ */
+// eslint-disable-next-line complexity
+function SSHError (callerName, err, { socket, credentials, socketConfig }) {
+ var theError
+ const session = socket.request.session
+
+ if (session) {
+ // we just want the first error of the session to pass to the client
+ session.error = session.error || ((err) ? err.message : undefined)
+ theError = session.error ? ': ' + session.error : ''
+
+ // log unsuccessful login attempt
+ if (err && (err.level === 'client-authentication')) {
+ console.log('WebSSH2 ' + 'error: Authentication failure'.red.bold +
+ ' user=' + credentials.username.yellow.bold.underline +
+ ' from=' + socket.handshake.address.yellow.bold.underline)
+
+ socket.emit('allowreauth', socketConfig.allowreauth)
+ socket.emit('reauth')
+ } else {
+ console.log('WebSSH2 Logout: user=' + credentials.username +
+ ' from=' + socket.handshake.address +
+ ' host=' + socketConfig.host +
+ ' port=' + socketConfig.port +
+ ' sessionID=' + socket.request.sessionID + '/' + socket.id +
+ ' allowreplay=' + socketConfig.allowreplay +
+ ' term=' + socketConfig.term
+ )
+ if (err) {
+ theError = err ? ': ' + err.message : ''
+ console.log('WebSSH2 error' + theError)
+ }
+ }
+
+ socket.emit('ssherror', 'SSH ' + callerName + theError)
+ session.destroy()
+ } else {
+ theError = (err) ? ': ' + err.message : ''
+ }
+
+ socket.disconnect(true)
+
+ debugWebSSH2('SSHError ' + callerName + theError)
+}
+
// public
module.exports = function socket (socket) {
- // if websocket connection arrives without an express session, kill it
- if (!socket.request.session) {
- socket.emit('401 UNAUTHORIZED')
- debugWebSSH2('SOCKET: No Express Session / REJECTED')
+ // create new config by merging config object from disk with config object from the request
+ const socketConfig = Object.assign({}, baseSocketConfig, getValidatedRequestConfig(socket.handshake.query))
+ const credentials = getCredentials(socket.request.session)
+ const hasCredentials = credentials.username && (credentials.userpassword || credentials.privatekey)
+ const errorContext = { socket, credentials, socketConfig };
+
+ if (!(hasCredentials && socketConfig)) {
+ debugWebSSH2('Attempt to connect without session.username/password or session varialbles defined, ' +
+ 'potentially previously abandoned client session. disconnecting websocket client.\r\n' +
+ 'Handshake 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)
return
}
// If configured, check that requsted host is in a permitted subnet
- if ( (((socket.request.session || {}).ssh || {}).allowedSubnets || {}).length && ( socket.request.session.ssh.allowedSubnets.length > 0 ) ) {
- var matcher = new CIDRMatcher(socket.request.session.ssh.allowedSubnets);
- if (!matcher.contains(socket.request.session.ssh.host)) {
+ if (socketConfig.allowedSubnets.length > 0) {
+ const matcher = new CIDRMatcher(socketConfig.allowedSubnets)
+ if (!matcher.contains(socketConfig.host)) {
console.log('WebSSH2 ' + 'error: Requested host outside configured subnets / REJECTED'.red.bold +
- ' user=' + socket.request.session.username.yellow.bold.underline +
- ' from=' + socket.handshake.address.yellow.bold.underline)
+ ' user=' + credentials.username.yellow.bold.underline +
+ ' from=' + socket.handshake.address.yellow.bold.underline)
socket.emit('ssherror', '401 UNAUTHORIZED')
socket.disconnect(true)
return
}
}
- var conn = new SSH()
+ const conn = new SSH()
+
socket.on('geometry', function socketOnGeometry (cols, rows) {
termCols = cols
termRows = rows
})
+
conn.on('banner', function connOnBanner (data) {
// need to convert to cr/lf for proper formatting
data = data.replace(/\r?\n/g, '\r\n')
@@ -49,35 +219,45 @@ module.exports = function socket (socket) {
})
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 + ' mrhsession=' + socket.request.session.ssh.mrhsession + ' allowreplay=' + socket.request.session.ssh.allowreplay + ' term=' + socket.request.session.ssh.term)
+ console.log('WebSSH2 Login: user=' + credentials.username +
+ ' from=' + socket.handshake.address +
+ ' host=' + socketConfig.host +
+ ' port=' + socketConfig.port +
+ ' sessionID=' + socket.request.sessionID + '/' + socket.id +
+ ' mrhsession=' + socketConfig.mrhsession +
+ ' allowreplay=' + socketConfig.allowreplay +
+ ' term=' + socketConfig.term
+ )
+
socket.emit('menu', menuData)
- socket.emit('allowreauth', socket.request.session.ssh.allowreauth)
- socket.emit('setTerminalOpts', socket.request.session.ssh.terminal)
- socket.emit('title', 'ssh://' + socket.request.session.ssh.host)
- if (socket.request.session.ssh.header.background) socket.emit('headerBackground', socket.request.session.ssh.header.background)
- if (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('allowreauth', socketConfig.allowreauth)
+ socket.emit('setTerminalOpts', socketConfig.terminal)
+ socket.emit('title', 'ssh://' + socketConfig.host)
+ if (socketConfig.header.background) socket.emit('headerBackground', socketConfig.header.background)
+ if (socketConfig.header.name) socket.emit('header', socketConfig.header.name)
+ socket.emit('footer', 'ssh://' + credentials.username + '@' + socketConfig.host + ':' + socketConfig.port)
socket.emit('status', 'SSH CONNECTION ESTABLISHED')
socket.emit('statusBackground', 'green')
- socket.emit('allowreplay', socket.request.session.ssh.allowreplay)
+ socket.emit('allowreplay', socketConfig.allowreplay)
+
conn.shell({
- term: socket.request.session.ssh.term,
+ term: socketConfig.term,
cols: termCols,
rows: termRows
}, function connShell (err, stream) {
if (err) {
- SSHerror('EXEC ERROR' + err)
+ SSHError('EXEC ERROR', err, errorContext)
conn.end()
return
}
// poc to log commands from client
- if (socket.request.session.ssh.serverlog.client) var dataBuffer
+ if (socketConfig.serverlog.client) var dataBuffer
socket.on('data', function socketOnData (data) {
stream.write(data)
// poc to log commands from client
- if (socket.request.session.ssh.serverlog.client) {
+ if (socketConfig.serverlog.client) {
if (data === '\r') {
- console.log('serverlog.client: ' + socket.request.session.id + '/' + socket.id + ' host: ' + socket.request.session.ssh.host + ' command: ' + dataBuffer)
+ console.log('serverlog.client: ' + socket.request.session.id + '/' + socket.id + ' host: ' + socketConfig.host + ' command: ' + dataBuffer)
dataBuffer = undefined
} else {
dataBuffer = (dataBuffer) ? dataBuffer + data : data
@@ -87,8 +267,8 @@ module.exports = function socket (socket) {
socket.on('control', function socketOnControl (controlData) {
switch (controlData) {
case 'replayCredentials':
- if (socket.request.session.ssh.allowreplay) {
- stream.write(socket.request.session.userpassword + '\n')
+ if (socketConfig.allowreplay) {
+ stream.write(credentials.userpassword + '\n')
}
/* falls through */
default:
@@ -102,19 +282,19 @@ module.exports = function socket (socket) {
socket.on('disconnect', function socketOnDisconnect (reason) {
debugWebSSH2('SOCKET DISCONNECT: ' + reason)
err = { message: reason }
- SSHerror('CLIENT SOCKET DISCONNECT', err)
+ SSHError('CLIENT SOCKET DISCONNECT', err, errorContext)
conn.end()
// socket.request.session.destroy()
})
socket.on('error', function socketOnError (err) {
- SSHerror('SOCKET ERROR', err)
+ SSHError('SOCKET ERROR', err, errorContext)
conn.end()
})
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)
+ SSHError('STREAM CLOSE', err, errorContext)
conn.end()
})
stream.stderr.on('data', function streamStderrOnData (data) {
@@ -123,71 +303,28 @@ module.exports = function socket (socket) {
})
})
- 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('end', function connOnEnd (err) { SSHError('CONN END BY HOST', err, errorContext) })
+ conn.on('close', function connOnClose (err) { SSHError('CONN CLOSE', err, errorContext) })
+ conn.on('error', function connOnError (err) { SSHError('CONN ERROR', err, errorContext) })
conn.on('keyboard-interactive', function connOnKeyboardInteractive (name, instructions, instructionsLang, prompts, finish) {
debugWebSSH2('conn.on(\'keyboard-interactive\')')
- finish([socket.request.session.userpassword])
+ finish([credentials.userpassword])
})
- if (socket.request.session.username && (socket.request.session.userpassword || socket.request.session.privatekey) && socket.request.session.ssh) {
- // console.log('hostkeys: ' + hostkeys[0].[0])
- conn.connect({
- host: socket.request.session.ssh.host,
- port: socket.request.session.ssh.port,
- localAddress: socket.request.session.ssh.localAddress,
- localPort: socket.request.session.ssh.localPort,
- username: socket.request.session.username,
- password: socket.request.session.userpassword,
- privateKey: socket.request.session.privatekey,
- tryKeyboard: true,
- algorithms: socket.request.session.ssh.algorithms,
- readyTimeout: socket.request.session.ssh.readyTimeout,
- keepaliveInterval: socket.request.session.ssh.keepaliveInterval,
- keepaliveCountMax: socket.request.session.ssh.keepaliveCountMax,
- debug: debug('ssh2')
- })
- } else {
- 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
- */
- // eslint-disable-next-line complexity
- 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)
- socket.emit('allowreauth', socket.request.session.ssh.allowreauth)
- socket.emit('reauth')
- } 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)
- if (err) {
- theError = (err) ? ': ' + err.message : ''
- console.log('WebSSH2 error' + theError)
- }
- }
- 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)
- }
+ // console.log('hostkeys: ' + hostkeys[0].[0])
+ conn.connect({
+ host: socketConfig.host,
+ port: socketConfig.port,
+ localAddress: socketConfig.localAddress,
+ localPort: socketConfig.localPort,
+ username: credentials.username,
+ password: credentials.userpassword,
+ privateKey: credentials.privatekey,
+ tryKeyboard: true,
+ algorithms: socketConfig.algorithms,
+ readyTimeout: socketConfig.readyTimeout,
+ keepaliveInterval: socketConfig.keepaliveInterval,
+ keepaliveCountMax: socketConfig.keepaliveCountMax,
+ debug: debug('ssh2')
+ })
}
diff --git a/app/server/util.js b/app/server/util.js
index 0ca3dca..a9357d0 100644
--- a/app/server/util.js
+++ b/app/server/util.js
@@ -4,37 +4,36 @@
// private
require('colors') // allow for color property extensions in log messages
+var config = require('./config')
var debug = require('debug')('WebSSH2')
var Auth = require('basic-auth')
-let defaultCredentials = {username: null, password: null, privatekey: null};
-
-exports.setDefaultCredentials = function (username, password, privatekey) {
- defaultCredentials.username = username
- defaultCredentials.password = password
- defaultCredentials.privatekey = privatekey
+exports.defaultCredentials = {
+ username: config.user.name,
+ userpassword: config.user.password,
+ privatekey: config.user.privatekey,
}
exports.basicAuth = function basicAuth (req, res, next) {
var myAuth = Auth(req)
+ let password = exports.defaultCredentials.userpassword
+
if (myAuth && myAuth.pass !== '') {
req.session.username = myAuth.name
- req.session.userpassword = myAuth.pass
+ req.session.userpassword = password = myAuth.pass
debug('myAuth.name: ' + myAuth.name.yellow.bold.underline +
' and password ' + ((myAuth.pass) ? 'exists'.yellow.bold.underline
: 'is blank'.underline.red.bold))
- } else {
- req.session.username = defaultCredentials.username;
- req.session.userpassword = defaultCredentials.password;
- req.session.privatekey = defaultCredentials.privatekey;
}
- if ( (!req.session.userpassword) && (!req.session.privatekey) ) {
+
+ if (!(password || exports.defaultCredentials.privatekey)) {
res.statusCode = 401
debug('basicAuth credential request (401)')
res.setHeader('WWW-Authenticate', 'Basic realm="WebSSH"')
res.end('Username and password required for web SSH service.')
return
}
+
next()
}