diff --git a/app/config.js b/app/config.js index 5594e06..5fe38de 100644 --- a/app/config.js +++ b/app/config.js @@ -67,7 +67,7 @@ const defaultConfig = { ssh: { host: null, port: 22, - term: "xterm-color", + term: "vt100", readyTimeout: 20000, keepaliveInterval: 120000, keepaliveCountMax: 10 diff --git a/app/connectionHandler.js b/app/connectionHandler.js index 8fbfca2..4c52493 100644 --- a/app/connectionHandler.js +++ b/app/connectionHandler.js @@ -3,6 +3,7 @@ const createDebug = require("debug") var path = require("path") var fs = require("fs") +const config = require("./config") var extend = require("util")._extend const debug = createDebug("webssh2:connectionHandler") @@ -34,6 +35,7 @@ function handleConnection(req, res, urlParams) { host: urlParams.host || sshCredentials.host || '', port: urlParams.port || sshCredentials.port || 22, username: sshCredentials.username || '', + term: urlParams.sshTerm || sshCredentials.term || config.ssh.term }, autoConnect: !!req.session.sshCredentials } diff --git a/app/routes.js b/app/routes.js index 716bfa9..5c39e8f 100644 --- a/app/routes.js +++ b/app/routes.js @@ -1,19 +1,19 @@ // server // /app/routes.js -const createDebug = require('debug') -const debug = createDebug('webssh2:routes') -const express = require('express') +const createDebug = require("debug") +const debug = createDebug("webssh2:routes") +const express = require("express") const router = express.Router() -const handleConnection = require('./connectionHandler') -const basicAuth = require('basic-auth') -const { sanitizeObject } = require('./utils') +const handleConnection = require("./connectionHandler") +const basicAuth = require("basic-auth") +const { sanitizeObject } = require("./utils") function auth(req, res, next) { - debug('Authenticating user with HTTP Basic Auth') + debug("Authenticating user with HTTP Basic Auth") var credentials = basicAuth(req) if (!credentials) { - res.setHeader('WWW-Authenticate', 'Basic realm="WebSSH2"') - return res.status(401).send('Authentication required.') + res.setHeader("WWW-Authenticate", 'Basic realm="WebSSH2"') + return res.status(401).send("Authentication required.") } // Store credentials in session req.session.sshCredentials = { @@ -24,36 +24,41 @@ function auth(req, res, next) { } // Scenario 1: No auth required, uses websocket authentication instead -router.get('/', function (req, res) { - debug('Accessed / route') +router.get("/", function (req, res) { + debug("Accessed / route") handleConnection(req, res) }) // Scenario 2: Auth required, uses HTTP Basic Auth -router.get('/host/:host', auth, function (req, res) { +router.get("/host/:host", auth, function (req, res) { debug(`Accessed /ssh/host/${req.params.host} route`) - const { host, port = 22 } = req.params; + const { host } = req.params + const { port = 22, sshTerm } = req.query + req.session.sshCredentials = req.session.sshCredentials || {} req.session.sshCredentials.host = host - req.session.sshCredentials.port = port + req.session.sshCredentials.port = parseInt(port, 10) + if (sshTerm) { + req.session.sshCredentials.term = sshTerm + } // Sanitize and log the sshCredentials object const sanitizedCredentials = sanitizeObject( JSON.parse(JSON.stringify(req.session.sshCredentials)) - ); - debug('/ssh//host/ Credentials: ', sanitizedCredentials); + ) + debug("/ssh/host/ Credentials: ", sanitizedCredentials) handleConnection(req, res, { host: req.params.host }) }) // Clear credentials route -router.post('/clear-credentials', function (req, res) { +router.post("/clear-credentials", function (req, res) { req.session.sshCredentials = null - res.status(200).send('Credentials cleared.') + res.status(200).send("Credentials cleared.") }) router.post("/force-reconnect", function (req, res) { - req.session.sshCredentials = null; - res.status(401).send("Authentication required."); -}); + req.session.sshCredentials = null + res.status(401).send("Authentication required.") +}) module.exports = router diff --git a/app/socket.js b/app/socket.js index fd62196..2d1c209 100644 --- a/app/socket.js +++ b/app/socket.js @@ -33,15 +33,16 @@ function handleConnection(socket, config) { setupInitialSocketListeners(socket, config) if (socket.handshake.session.sshCredentials) { - const { username, password, host, port } = - socket.handshake.session.sshCredentials + const creds = socket.handshake.session.sshCredentials + const { username, password, host, port } = creds + debug(`Credentials from session: ${socket.id}, Host: ${host}`, creds) if (username && password && host && port) { - handleAuthentication(socket, { username, password, host, port }, config) + handleAuthentication(socket, creds, config) return } } - + // Emit an event to the client to request authentication if (!authenticated) { debug( @@ -209,10 +210,10 @@ function handleConnection(socket, config) { * @param {import('socket.io').Socket} socket - The Socket.IO socket * @param {Credentials} creds - The user credentials */ - function initializeShell(socket, creds) { + function initializeShell (socket, creds) { conn.shell( { - term: creds.term, + term: creds.term || 'vt69', // config.ssh.term, cols: creds.cols, rows: creds.rows }, @@ -329,11 +330,11 @@ function handleConnection(socket, config) { * @param {string} controlData - The control command * @param {Object} config - The configuration object */ - function handleControl(socket, stream, credentials, controlData, config) { + function handleControl(socket, stream, creds, controlData, config) { debug(`Received control data: ${controlData}`) - if (controlData === "replayCredentials" && stream && credentials) { - replayCredentials(socket, stream, credentials, config) + if (controlData === "replayCredentials" && stream && creds) { + replayCredentials(socket, stream, creds, config) } else if (controlData === "reauth" && config.options.allowReauth) { handleReauth(socket) } @@ -427,7 +428,7 @@ function handleConnection(socket, config) { readyTimeout: credentials.readyTimeout, keepaliveInterval: credentials.keepaliveInterval, keepaliveCountMax: credentials.keepaliveCountMax, - debug: createDebug("webssh2:ssh") + debug: createDebug("ssh") } } }