fix: correct handling of sshTerm query parameters

This commit is contained in:
Bill Church 2024-08-14 01:05:51 +00:00
parent 266f9876d3
commit b9ca79e7cf
No known key found for this signature in database
4 changed files with 40 additions and 32 deletions

View file

@ -67,7 +67,7 @@ const defaultConfig = {
ssh: { ssh: {
host: null, host: null,
port: 22, port: 22,
term: "xterm-color", term: "vt100",
readyTimeout: 20000, readyTimeout: 20000,
keepaliveInterval: 120000, keepaliveInterval: 120000,
keepaliveCountMax: 10 keepaliveCountMax: 10

View file

@ -3,6 +3,7 @@
const createDebug = require("debug") const createDebug = require("debug")
var path = require("path") var path = require("path")
var fs = require("fs") var fs = require("fs")
const config = require("./config")
var extend = require("util")._extend var extend = require("util")._extend
const debug = createDebug("webssh2:connectionHandler") const debug = createDebug("webssh2:connectionHandler")
@ -34,6 +35,7 @@ function handleConnection(req, res, urlParams) {
host: urlParams.host || sshCredentials.host || '', host: urlParams.host || sshCredentials.host || '',
port: urlParams.port || sshCredentials.port || 22, port: urlParams.port || sshCredentials.port || 22,
username: sshCredentials.username || '', username: sshCredentials.username || '',
term: urlParams.sshTerm || sshCredentials.term || config.ssh.term
}, },
autoConnect: !!req.session.sshCredentials autoConnect: !!req.session.sshCredentials
} }

View file

@ -1,19 +1,19 @@
// server // server
// /app/routes.js // /app/routes.js
const createDebug = require('debug') const createDebug = require("debug")
const debug = createDebug('webssh2:routes') const debug = createDebug("webssh2:routes")
const express = require('express') const express = require("express")
const router = express.Router() const router = express.Router()
const handleConnection = require('./connectionHandler') const handleConnection = require("./connectionHandler")
const basicAuth = require('basic-auth') const basicAuth = require("basic-auth")
const { sanitizeObject } = require('./utils') const { sanitizeObject } = require("./utils")
function auth(req, res, next) { function auth(req, res, next) {
debug('Authenticating user with HTTP Basic Auth') debug("Authenticating user with HTTP Basic Auth")
var credentials = basicAuth(req) var credentials = basicAuth(req)
if (!credentials) { if (!credentials) {
res.setHeader('WWW-Authenticate', 'Basic realm="WebSSH2"') res.setHeader("WWW-Authenticate", 'Basic realm="WebSSH2"')
return res.status(401).send('Authentication required.') return res.status(401).send("Authentication required.")
} }
// Store credentials in session // Store credentials in session
req.session.sshCredentials = { req.session.sshCredentials = {
@ -24,36 +24,41 @@ function auth(req, res, next) {
} }
// Scenario 1: No auth required, uses websocket authentication instead // Scenario 1: No auth required, uses websocket authentication instead
router.get('/', function (req, res) { router.get("/", function (req, res) {
debug('Accessed / route') debug("Accessed / route")
handleConnection(req, res) handleConnection(req, res)
}) })
// Scenario 2: Auth required, uses HTTP Basic Auth // 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`) 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.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 // Sanitize and log the sshCredentials object
const sanitizedCredentials = sanitizeObject( const sanitizedCredentials = sanitizeObject(
JSON.parse(JSON.stringify(req.session.sshCredentials)) JSON.parse(JSON.stringify(req.session.sshCredentials))
); )
debug('/ssh//host/ Credentials: ', sanitizedCredentials); debug("/ssh/host/ Credentials: ", sanitizedCredentials)
handleConnection(req, res, { host: req.params.host }) handleConnection(req, res, { host: req.params.host })
}) })
// Clear credentials route // Clear credentials route
router.post('/clear-credentials', function (req, res) { router.post("/clear-credentials", function (req, res) {
req.session.sshCredentials = null req.session.sshCredentials = null
res.status(200).send('Credentials cleared.') res.status(200).send("Credentials cleared.")
}) })
router.post("/force-reconnect", function (req, res) { router.post("/force-reconnect", function (req, res) {
req.session.sshCredentials = null; req.session.sshCredentials = null
res.status(401).send("Authentication required."); res.status(401).send("Authentication required.")
}); })
module.exports = router module.exports = router

View file

@ -33,11 +33,12 @@ function handleConnection(socket, config) {
setupInitialSocketListeners(socket, config) setupInitialSocketListeners(socket, config)
if (socket.handshake.session.sshCredentials) { if (socket.handshake.session.sshCredentials) {
const { username, password, host, port } = const creds = socket.handshake.session.sshCredentials
socket.handshake.session.sshCredentials const { username, password, host, port } = creds
debug(`Credentials from session: ${socket.id}, Host: ${host}`, creds)
if (username && password && host && port) { if (username && password && host && port) {
handleAuthentication(socket, { username, password, host, port }, config) handleAuthentication(socket, creds, config)
return return
} }
} }
@ -209,10 +210,10 @@ function handleConnection(socket, config) {
* @param {import('socket.io').Socket} socket - The Socket.IO socket * @param {import('socket.io').Socket} socket - The Socket.IO socket
* @param {Credentials} creds - The user credentials * @param {Credentials} creds - The user credentials
*/ */
function initializeShell(socket, creds) { function initializeShell (socket, creds) {
conn.shell( conn.shell(
{ {
term: creds.term, term: creds.term || 'vt69', // config.ssh.term,
cols: creds.cols, cols: creds.cols,
rows: creds.rows rows: creds.rows
}, },
@ -329,11 +330,11 @@ function handleConnection(socket, config) {
* @param {string} controlData - The control command * @param {string} controlData - The control command
* @param {Object} config - The configuration object * @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}`) debug(`Received control data: ${controlData}`)
if (controlData === "replayCredentials" && stream && credentials) { if (controlData === "replayCredentials" && stream && creds) {
replayCredentials(socket, stream, credentials, config) replayCredentials(socket, stream, creds, config)
} else if (controlData === "reauth" && config.options.allowReauth) { } else if (controlData === "reauth" && config.options.allowReauth) {
handleReauth(socket) handleReauth(socket)
} }
@ -427,7 +428,7 @@ function handleConnection(socket, config) {
readyTimeout: credentials.readyTimeout, readyTimeout: credentials.readyTimeout,
keepaliveInterval: credentials.keepaliveInterval, keepaliveInterval: credentials.keepaliveInterval,
keepaliveCountMax: credentials.keepaliveCountMax, keepaliveCountMax: credentials.keepaliveCountMax,
debug: createDebug("webssh2:ssh") debug: createDebug("ssh")
} }
} }
} }