From edb66620c13ac863aa23a2321df193021df0a7c0 Mon Sep 17 00:00:00 2001 From: David Koch Gregersen Date: Tue, 7 Mar 2023 10:43:34 +0100 Subject: [PATCH] Adding a check when reading ssh config file Also adds comments to the createRemoteEngineConfiguration function --- apps/api/src/lib/common.ts | 39 +++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/api/src/lib/common.ts b/apps/api/src/lib/common.ts index 4ef8790f9..8832fdb8a 100644 --- a/apps/api/src/lib/common.ts +++ b/apps/api/src/lib/common.ts @@ -11,7 +11,7 @@ import { promises as dns } from 'dns'; import * as Sentry from '@sentry/node'; import { PrismaClient } from '@prisma/client'; import os from 'os'; -import sshConfig from 'ssh-config'; +import * as SSHConfig from 'ssh-config/src/ssh-config'; import jsonwebtoken from 'jsonwebtoken'; import { checkContainer, removeContainer } from './docker'; import { day } from './dayjs'; @@ -498,35 +498,56 @@ export async function getFreeSSHLocalPort(id: string): Promise return false; } +/** + * Update the ssh config file with a host + * + * @param id Destination ID + * @returns + */ export async function createRemoteEngineConfiguration(id: string) { - const homedir = os.homedir(); const sshKeyFile = `/tmp/id_rsa-${id}`; const localPort = await getFreeSSHLocalPort(id); const { sshKey: { privateKey }, - network, remoteIpAddress, remotePort, remoteUser } = await prisma.destinationDocker.findFirst({ where: { id }, include: { sshKey: true } }); + + // Write new keyfile await fs.writeFile(sshKeyFile, decrypt(privateKey) + '\n', { encoding: 'utf8', mode: 400 }); - const currentConfigFileContent = (await fs.readFile(`${homedir}/.ssh/config`)).toString(); - const config = sshConfig.parse(currentConfigFileContent.toString()); const Host = `${remoteIpAddress}-remote`; + // Removes previous ssh-keys try { await executeCommand({ command: `ssh-keygen -R ${Host}` }); await executeCommand({ command: `ssh-keygen -R ${remoteIpAddress}` }); await executeCommand({ command: `ssh-keygen -R localhost:${localPort}` }); - } catch (error) { } + } catch (error) { + // + } + const homedir = os.homedir(); + let currentConfigFileContent = ''; + try { + // Read the current config file + currentConfigFileContent = (await fs.readFile(`${homedir}/.ssh/config`)).toString(); + } catch (error) { + // File doesn't exist, so we do nothing, a new one is going to be created + } + + // Parse the config file + const config = SSHConfig.parse(currentConfigFileContent); + + // Remove current config for the given host const found = config.find({ Host }); const foundIp = config.find({ Host: remoteIpAddress }); if (found) config.remove({ Host }); if (foundIp) config.remove({ Host: remoteIpAddress }); + // Create the new config config.append({ Host, Hostname: remoteIpAddress, @@ -539,13 +560,17 @@ export async function createRemoteEngineConfiguration(id: string) { ControlPersist: '10m' }); + // Check if .ssh folder exists, and if not create one try { await fs.stat(`${homedir}/.ssh/`); } catch (error) { await fs.mkdir(`${homedir}/.ssh/`); } - return await fs.writeFile(`${homedir}/.ssh/config`, sshConfig.stringify(config)); + + // Write the config + return await fs.writeFile(`${homedir}/.ssh/config`, SSHConfig.stringify(config)); } + export async function executeCommand({ command, dockerId = null,