From 75785c463ceaf49d0ec63de60c1d594f3db61601 Mon Sep 17 00:00:00 2001 From: butlerx Date: Wed, 18 Nov 2020 12:07:32 +0000 Subject: [PATCH] #300 Enforce remote-user header when a user logs in --- src/server.ts | 2 +- src/server/command.ts | 31 ++++++++++++++----------------- src/server/command/address.ts | 13 +++++++++++-- src/server/login.ts | 8 -------- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/server.ts b/src/server.ts index 27f9ec5..b06f056 100644 --- a/src/server.ts +++ b/src/server.ts @@ -47,7 +47,7 @@ export async function start( * @name connection */ logger.info('Connection accepted.'); - const { args, user: sshUser } = getCommand(socket, ssh, command, forcessh); + const [args, sshUser] = getCommand(socket, ssh, command, forcessh); logger.debug('Command Generated', { user: sshUser, cmd: args.join(' '), diff --git a/src/server/command.ts b/src/server/command.ts index f60cc24..960ff92 100644 --- a/src/server/command.ts +++ b/src/server/command.ts @@ -15,11 +15,9 @@ const urlArgs = ( ): { [s: string]: string } => Object.assign(def, url.parse(referer, true).query); -export const getCommand = ( +export function getCommand( { - request: { - headers: { referer }, - }, + request: { headers }, client: { conn: { remoteAddress }, }, @@ -27,13 +25,15 @@ export const getCommand = ( { user, host, port, auth, pass, key, knownHosts, config }: SSH, command: string, forcessh: boolean, -): { args: string[]; user: boolean } => ({ - args: - !forcessh && localhost(host) - ? loginOptions(command, remoteAddress) - : sshOptions( +): [string[], boolean] { + const sshAddress = address(headers, user, host); + const localLogin = !forcessh && localhost(host); + return localLogin + ? [loginOptions(command, remoteAddress), localLogin] + : [ + sshOptions( { - ...urlArgs(referer, { + ...urlArgs(headers.referer, { port: `${port}`, pass: pass || '', command, @@ -41,13 +41,10 @@ export const getCommand = ( knownHosts, config: config || '', }), - host: address(referer, user, host), + host: sshAddress, }, key, ), - user: - (!forcessh && localhost(host)) || - user !== '' || - user.includes('@') || - address(referer, user, host).includes('@'), -}); + user !== '' || user.includes('@') || sshAddress.includes('@'), + ]; +} diff --git a/src/server/command/address.ts b/src/server/command/address.ts index 4ff8c9b..8ba9249 100644 --- a/src/server/command/address.ts +++ b/src/server/command/address.ts @@ -1,5 +1,14 @@ -export function address(referer: string, user: string, host: string): string { - const match = referer.match('.+/ssh/([^/]+)$'); +export function address( + headers: Record, + user: string, + host: string, +): string { + // Check request-header for username + const remoteUser = headers['remote-user']; + if (remoteUser) { + return `${remoteUser}@${host}`; + } + const match = headers.referer.match('.+/ssh/([^/]+)$'); const fallback = user ? `${user}@${host}` : host; return match ? `${match[1].split('?')[0]}@${host}` : fallback; } diff --git a/src/server/login.ts b/src/server/login.ts index 7dcf6f7..1b8b890 100644 --- a/src/server/login.ts +++ b/src/server/login.ts @@ -11,14 +11,6 @@ const executable = resolvePath( ); export function login(socket: SocketIO.Socket): Promise { - // Check request-header for username - const remoteUser = socket.request.headers['remote-user']; - if (remoteUser) { - return new Promise(resolve => { - resolve(remoteUser); - }); - } - // Request carries no username information // Create terminal and ask user for username const term = pty.spawn('/usr/bin/env', ['node', executable], xterm);