fix: username/password in config file no longer honored #374
This commit is contained in:
parent
eb8f6203bb
commit
4185df77f6
3 changed files with 94 additions and 64 deletions
|
@ -1 +1 @@
|
||||||
nodejs 6.9.1
|
nodejs 23.2.0
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
const express = require("express")
|
const express = require("express")
|
||||||
const config = require("./config")
|
const config = require("./config")
|
||||||
const socketHandler = require("./socket")
|
const socketHandler = require("./socket")
|
||||||
const sshRoutes = require("./routes")
|
const sshRoutes = require("./routes")(config)
|
||||||
const { applyMiddleware } = require("./middleware")
|
const { applyMiddleware } = require("./middleware")
|
||||||
const { createServer, startServer } = require("./server")
|
const { createServer, startServer } = require("./server")
|
||||||
const { configureSocketIO } = require("./io")
|
const { configureSocketIO } = require("./io")
|
||||||
|
|
154
app/routes.js
154
app/routes.js
|
@ -16,72 +16,102 @@ const { ConfigError, handleError } = require("./errors")
|
||||||
const { HTTP } = require("./constants")
|
const { HTTP } = require("./constants")
|
||||||
|
|
||||||
const debug = createNamespacedDebug("routes")
|
const debug = createNamespacedDebug("routes")
|
||||||
const router = express.Router()
|
|
||||||
|
|
||||||
// eslint-disable-next-line consistent-return
|
module.exports = function(config) {
|
||||||
function auth(req, res, next) {
|
const router = express.Router()
|
||||||
debug("auth: Basic Auth")
|
|
||||||
const credentials = basicAuth(req)
|
|
||||||
if (!credentials) {
|
|
||||||
res.setHeader(HTTP.AUTHENTICATE, HTTP.REALM)
|
|
||||||
return res.status(HTTP.UNAUTHORIZED).send(HTTP.AUTH_REQUIRED)
|
|
||||||
}
|
|
||||||
// Validate and sanitize credentials
|
|
||||||
req.session.sshCredentials = {
|
|
||||||
username: validator.escape(credentials.name),
|
|
||||||
password: credentials.pass // We don't sanitize the password as it might contain special characters
|
|
||||||
}
|
|
||||||
req.session.usedBasicAuth = true // Set this flag when Basic Auth is used
|
|
||||||
next()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scenario 1: No auth required, uses websocket authentication instead
|
/**
|
||||||
router.get("/", (req, res) => {
|
* Middleware function that handles HTTP Basic Authentication for the application.
|
||||||
debug("router.get./: Accessed / route")
|
*
|
||||||
handleConnection(req, res)
|
* If the `config.user.name` and `config.user.password` are set, it will use those
|
||||||
})
|
* credentials to authenticate the request and set the `req.session.sshCredentials`
|
||||||
|
* object with the username and password.
|
||||||
// Scenario 2: Auth required, uses HTTP Basic Auth
|
*
|
||||||
router.get("/host/:host", auth, (req, res) => {
|
* If the `config.user.name` and `config.user.password` are not set, it will attempt
|
||||||
debug(`router.get.host: /ssh/host/${req.params.host} route`)
|
* to use HTTP Basic Authentication to authenticate the request. It will validate and
|
||||||
|
* sanitize the credentials, and set the `req.session.sshCredentials` object with the
|
||||||
try {
|
* username and password.
|
||||||
const host = getValidatedHost(req.params.host)
|
*
|
||||||
const port = getValidatedPort(req.query.port)
|
* The function will also set the `req.session.usedBasicAuth` flag to indicate that
|
||||||
|
* Basic Authentication was used.
|
||||||
// Validate and sanitize sshterm parameter if it exists
|
*
|
||||||
const sshterm = validateSshTerm(req.query.sshterm)
|
* If the authentication fails, the function will send a 401 Unauthorized response
|
||||||
|
* with the appropriate WWW-Authenticate header.
|
||||||
req.session.sshCredentials = req.session.sshCredentials || {}
|
*/
|
||||||
req.session.sshCredentials.host = host
|
// eslint-disable-next-line consistent-return
|
||||||
req.session.sshCredentials.port = port
|
function auth(req, res, next) {
|
||||||
if (req.query.sshterm) {
|
if (config.user.name && config.user.password) {
|
||||||
req.session.sshCredentials.term = sshterm
|
req.session.sshCredentials = {
|
||||||
|
username: config.user.name,
|
||||||
|
password: config.user.password
|
||||||
|
}
|
||||||
|
req.session.usedBasicAuth = true
|
||||||
|
return next()
|
||||||
}
|
}
|
||||||
req.session.usedBasicAuth = true
|
// Scenario 2: Basic Auth
|
||||||
|
debug("auth: Basic Auth")
|
||||||
// Sanitize and log the sshCredentials object
|
const credentials = basicAuth(req)
|
||||||
const sanitizedCredentials = maskSensitiveData(
|
if (!credentials) {
|
||||||
JSON.parse(JSON.stringify(req.session.sshCredentials))
|
res.setHeader(HTTP.AUTHENTICATE, HTTP.REALM)
|
||||||
)
|
return res.status(HTTP.UNAUTHORIZED).send(HTTP.AUTH_REQUIRED)
|
||||||
debug("/ssh/host/ Credentials: ", sanitizedCredentials)
|
}
|
||||||
|
// Validate and sanitize credentials
|
||||||
handleConnection(req, res, { host: host })
|
req.session.sshCredentials = {
|
||||||
} catch (err) {
|
username: validator.escape(credentials.name),
|
||||||
const error = new ConfigError(`Invalid configuration: ${err.message}`)
|
password: credentials.pass // We don't sanitize the password as it might contain special characters
|
||||||
handleError(error, res)
|
}
|
||||||
|
req.session.usedBasicAuth = true // Set this flag when Basic Auth is used
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
// Clear credentials route
|
// Scenario 1: No auth required, uses websocket authentication instead
|
||||||
router.get("/clear-credentials", (req, res) => {
|
router.get("/", (req, res) => {
|
||||||
req.session.sshCredentials = null
|
debug("router.get./: Accessed / route")
|
||||||
res.status(HTTP.OK).send(HTTP.CREDENTIALS_CLEARED)
|
handleConnection(req, res)
|
||||||
})
|
})
|
||||||
|
|
||||||
router.get("/force-reconnect", (req, res) => {
|
// Scenario 2: Auth required, uses HTTP Basic Auth
|
||||||
req.session.sshCredentials = null
|
router.get("/host/:host", auth, (req, res) => {
|
||||||
res.status(HTTP.UNAUTHORIZED).send(HTTP.AUTH_REQUIRED)
|
debug(`router.get.host: /ssh/host/${req.params.host} route`)
|
||||||
})
|
|
||||||
|
|
||||||
module.exports = router
|
try {
|
||||||
|
const host = getValidatedHost(req.params.host)
|
||||||
|
const port = getValidatedPort(req.query.port)
|
||||||
|
|
||||||
|
// Validate and sanitize sshterm parameter if it exists
|
||||||
|
const sshterm = validateSshTerm(req.query.sshterm)
|
||||||
|
|
||||||
|
req.session.sshCredentials = req.session.sshCredentials || {}
|
||||||
|
req.session.sshCredentials.host = host
|
||||||
|
req.session.sshCredentials.port = port
|
||||||
|
if (req.query.sshterm) {
|
||||||
|
req.session.sshCredentials.term = sshterm
|
||||||
|
}
|
||||||
|
req.session.usedBasicAuth = true
|
||||||
|
|
||||||
|
// Sanitize and log the sshCredentials object
|
||||||
|
const sanitizedCredentials = maskSensitiveData(
|
||||||
|
JSON.parse(JSON.stringify(req.session.sshCredentials))
|
||||||
|
)
|
||||||
|
debug("/ssh/host/ Credentials: ", sanitizedCredentials)
|
||||||
|
|
||||||
|
handleConnection(req, res, { host: host })
|
||||||
|
} catch (err) {
|
||||||
|
const error = new ConfigError(`Invalid configuration: ${err.message}`)
|
||||||
|
handleError(error, res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Clear credentials route
|
||||||
|
router.get("/clear-credentials", (req, res) => {
|
||||||
|
req.session.sshCredentials = null
|
||||||
|
res.status(HTTP.OK).send(HTTP.CREDENTIALS_CLEARED)
|
||||||
|
})
|
||||||
|
|
||||||
|
router.get("/force-reconnect", (req, res) => {
|
||||||
|
req.session.sshCredentials = null
|
||||||
|
res.status(HTTP.UNAUTHORIZED).send(HTTP.AUTH_REQUIRED)
|
||||||
|
})
|
||||||
|
|
||||||
|
return router
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue