fix: handle http basic auth in /ssh/host/
route
This commit is contained in:
parent
aa633aef0b
commit
1fc35f74da
3 changed files with 81 additions and 41 deletions
|
@ -7,56 +7,53 @@ var extend = require("util")._extend
|
|||
function handleConnection(req, res, urlParams) {
|
||||
urlParams = urlParams || {}
|
||||
|
||||
// The path to the client directory of the webssh2 module.
|
||||
var clientPath = path.resolve(
|
||||
const clientPath = path.resolve(
|
||||
__dirname,
|
||||
"..",
|
||||
"node_modules",
|
||||
"webssh2_client",
|
||||
"client",
|
||||
"public"
|
||||
'..',
|
||||
'node_modules',
|
||||
'webssh2_client',
|
||||
'client',
|
||||
'public'
|
||||
)
|
||||
|
||||
// Combine URL parameters, query parameters, and form data
|
||||
var connectionParams = extend({}, urlParams)
|
||||
const connectionParams = extend({}, urlParams)
|
||||
extend(connectionParams, req.query)
|
||||
extend(connectionParams, req.body || {})
|
||||
|
||||
// Inject configuration
|
||||
var config = {
|
||||
const sshCredentials = req.session.sshCredentials || {}
|
||||
|
||||
const config = {
|
||||
socket: {
|
||||
url: req.protocol + "://" + req.get("host"),
|
||||
path: "/ssh/socket.io"
|
||||
url: req.protocol + '://' + req.get('host'),
|
||||
path: '/ssh/socket.io'
|
||||
},
|
||||
ssh: {
|
||||
host: urlParams.host || "",
|
||||
port: urlParams.port || 22
|
||||
host: urlParams.host || sshCredentials.host || '',
|
||||
port: urlParams.port || sshCredentials.port || 22,
|
||||
username: sshCredentials.username || '',
|
||||
password: sshCredentials.password || ''
|
||||
},
|
||||
autoConnect: !!req.session.sshCredentials
|
||||
}
|
||||
|
||||
// Read the client.htm file
|
||||
fs.readFile(
|
||||
path.join(clientPath, "client.htm"),
|
||||
"utf8",
|
||||
path.join(clientPath, 'client.htm'),
|
||||
'utf8',
|
||||
function (err, data) {
|
||||
if (err) {
|
||||
return res.status(500).send("Error loading client file")
|
||||
return res.status(500).send('Error loading client file')
|
||||
}
|
||||
|
||||
// Replace relative paths with the correct path
|
||||
var modifiedHtml = data.replace(
|
||||
/(src|href)="(?!http|\/\/)/g,
|
||||
'$1="/ssh/assets/'
|
||||
)
|
||||
|
||||
// Inject the configuration into the HTML
|
||||
modifiedHtml = modifiedHtml.replace(
|
||||
"window.webssh2Config = null;",
|
||||
"window.webssh2Config = " + JSON.stringify(config) + ";"
|
||||
'window.webssh2Config = null;',
|
||||
'window.webssh2Config = ' + JSON.stringify(config) + ';'
|
||||
)
|
||||
|
||||
// Send the modified HTML
|
||||
res.send(modifiedHtml)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,34 +1,48 @@
|
|||
// 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 handleConnection = require('./connectionHandler')
|
||||
const basicAuth = require('basic-auth')
|
||||
|
||||
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 = credentials
|
||||
req.session.sshCredentials = {
|
||||
username: credentials.name,
|
||||
password: credentials.pass
|
||||
}
|
||||
next()
|
||||
}
|
||||
|
||||
// Scenario 1: No auth required, uses websocket authentication instead
|
||||
router.get("/", function (req, res) {
|
||||
debug("Accessed /ssh 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`)
|
||||
handleConnection(req, res, { host: req.params.host })
|
||||
})
|
||||
|
||||
// Clear credentials route
|
||||
router.post('/clear-credentials', function (req, res) {
|
||||
req.session.sshCredentials = null
|
||||
res.status(200).send('Credentials cleared.')
|
||||
})
|
||||
|
||||
router.post("/force-reconnect", function (req, res) {
|
||||
req.session.sshCredentials = null;
|
||||
res.status(401).send("Authentication required.");
|
||||
});
|
||||
|
||||
module.exports = router
|
||||
|
|
|
@ -86,12 +86,27 @@ function handleConnection(socket, config) {
|
|||
* @param {Object} config - The configuration object
|
||||
*/
|
||||
function handleAuthentication(socket, creds, config) {
|
||||
debug(`AUTHENTICATE: ${socket.id}, Host: ${creds.host}`)
|
||||
// If reauth, creds from this function should take precedence
|
||||
if (creds && isValidCredentials(creds)) {
|
||||
// Store new credentials in session, overriding any existing ones
|
||||
socket.handshake.session.sshCredentials = {
|
||||
username: creds.username,
|
||||
password: creds.password,
|
||||
host: creds.host,
|
||||
port: creds.port
|
||||
}
|
||||
|
||||
if (isValidCredentials(creds)) {
|
||||
debug(`CREDENTIALS VALID: ${socket.id}, Host: ${creds.host}`)
|
||||
// Save the session after updating
|
||||
socket.handshake.session.save((err) => {
|
||||
if (err) {
|
||||
console.error(`Failed to save session for ${socket.id}:`, err)
|
||||
}
|
||||
})
|
||||
|
||||
// Proceed with connection initialization using the new credentials
|
||||
initializeConnection(socket, creds, config)
|
||||
} else {
|
||||
// Handle invalid credentials scenario
|
||||
debug(`CREDENTIALS INVALID: ${socket.id}, Host: ${creds.host}`)
|
||||
socket.emit("authentication", {
|
||||
success: false,
|
||||
|
@ -331,8 +346,22 @@ function handleConnection(socket, config) {
|
|||
*/
|
||||
function handleReauth(socket) {
|
||||
debug(`Reauthentication requested for ${socket.id}`)
|
||||
socket.emit("authentication", { action: "reauth" })
|
||||
handleConnectionClose(socket)
|
||||
|
||||
// Clear existing session credentials
|
||||
socket.handshake.session.sshCredentials = null
|
||||
|
||||
// Save the session after modification
|
||||
socket.handshake.session.save((err) => {
|
||||
if (err) {
|
||||
console.error(`Failed to save session for ${socket.id}:`, err)
|
||||
}
|
||||
|
||||
// Notify client to reauthenticate
|
||||
socket.emit("authentication", { action: "reauth" })
|
||||
|
||||
// Close the current connection to enforce reauthentication
|
||||
handleConnectionClose(socket)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue