Browse Source

#300 Enforce remote-user header when a user logs in

pull/303/head
butlerx 4 years ago
parent
commit
75785c463c
No known key found for this signature in database GPG Key ID: B37CA765BAA89170
  1. 2
      src/server.ts
  2. 31
      src/server/command.ts
  3. 13
      src/server/command/address.ts
  4. 8
      src/server/login.ts

2
src/server.ts

@ -47,7 +47,7 @@ export async function start(
* @name connection * @name connection
*/ */
logger.info('Connection accepted.'); 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', { logger.debug('Command Generated', {
user: sshUser, user: sshUser,
cmd: args.join(' '), cmd: args.join(' '),

31
src/server/command.ts

@ -15,11 +15,9 @@ const urlArgs = (
): { [s: string]: string } => ): { [s: string]: string } =>
Object.assign(def, url.parse(referer, true).query); Object.assign(def, url.parse(referer, true).query);
export const getCommand = ( export function getCommand(
{ {
request: { request: { headers },
headers: { referer },
},
client: { client: {
conn: { remoteAddress }, conn: { remoteAddress },
}, },
@ -27,13 +25,15 @@ export const getCommand = (
{ user, host, port, auth, pass, key, knownHosts, config }: SSH, { user, host, port, auth, pass, key, knownHosts, config }: SSH,
command: string, command: string,
forcessh: boolean, forcessh: boolean,
): { args: string[]; user: boolean } => ({ ): [string[], boolean] {
args: const sshAddress = address(headers, user, host);
!forcessh && localhost(host) const localLogin = !forcessh && localhost(host);
? loginOptions(command, remoteAddress) return localLogin
: sshOptions( ? [loginOptions(command, remoteAddress), localLogin]
: [
sshOptions(
{ {
...urlArgs(referer, { ...urlArgs(headers.referer, {
port: `${port}`, port: `${port}`,
pass: pass || '', pass: pass || '',
command, command,
@ -41,13 +41,10 @@ export const getCommand = (
knownHosts, knownHosts,
config: config || '', config: config || '',
}), }),
host: address(referer, user, host), host: sshAddress,
}, },
key, key,
), ),
user: user !== '' || user.includes('@') || sshAddress.includes('@'),
(!forcessh && localhost(host)) || ];
user !== '' || }
user.includes('@') ||
address(referer, user, host).includes('@'),
});

13
src/server/command/address.ts

@ -1,5 +1,14 @@
export function address(referer: string, user: string, host: string): string { export function address(
const match = referer.match('.+/ssh/([^/]+)$'); headers: Record<string, string>,
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; const fallback = user ? `${user}@${host}` : host;
return match ? `${match[1].split('?')[0]}@${host}` : fallback; return match ? `${match[1].split('?')[0]}@${host}` : fallback;
} }

8
src/server/login.ts

@ -11,14 +11,6 @@ const executable = resolvePath(
); );
export function login(socket: SocketIO.Socket): Promise<string> { export function login(socket: SocketIO.Socket): Promise<string> {
// 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 // Request carries no username information
// Create terminal and ask user for username // Create terminal and ask user for username
const term = pty.spawn('/usr/bin/env', ['node', executable], xterm); const term = pty.spawn('/usr/bin/env', ['node', executable], xterm);

Loading…
Cancel
Save