ssh tunnel - alternative modes

This commit is contained in:
Jan Prochazka
2021-02-13 12:13:10 +01:00
parent 114dc0b543
commit 1076fb8391
12 changed files with 185 additions and 18 deletions

View File

@@ -1,4 +1,5 @@
const currentVersion = require('../currentVersion');
const platformInfo = require('../utility/platformInfo');
module.exports = {
get_meta: 'get',
@@ -31,4 +32,10 @@ module.exports = {
...currentVersion,
};
},
platformInfo_meta: 'get',
async platformInfo() {
return platformInfo;
},
};

View File

@@ -24,6 +24,7 @@ const requirePluginsTemplate = plugins =>
const scriptTemplate = script => `
const dbgateApi = require(process.env.DBGATE_API);
dbgateApi.registerProcessCommunication();
${requirePluginsTemplate(extractPlugins(script))}
require=null;
async function run() {
@@ -36,6 +37,7 @@ dbgateApi.runScript(run);
const loaderScriptTemplate = (functionName, props, runid) => `
const dbgateApi = require(process.env.DBGATE_API);
dbgateApi.registerProcessCommunication();
${requirePluginsTemplate(extractShellApiPlugins(functionName, props))}
require=null;
async function run() {

View File

@@ -17,6 +17,7 @@ const requirePlugin = require('./requirePlugin');
const download = require('./download');
const executeQuery = require('./executeQuery');
const loadFile = require('./loadFile');
const registerProcessCommunication = require('./registerProcessCommunication');
const dbgateApi = {
queryReader,
@@ -37,6 +38,7 @@ const dbgateApi = {
registerPlugins,
executeQuery,
loadFile,
registerProcessCommunication,
};
requirePlugin.initializeDbgateApi(dbgateApi);

View File

@@ -0,0 +1,9 @@
const { handleProcessCommunication } = require('../utility/processComm');
async function registerProcessCommunication() {
process.on('message', async message => {
handleProcessCommunication(message);
});
}
module.exports = registerProcessCommunication;

View File

@@ -42,31 +42,45 @@ function getEncryptor() {
return _encryptor;
}
function encryptConnection(connection) {
function encryptPasswordField(connection, field) {
if (
connection &&
connection.password &&
!connection.password.startsWith('crypt:') &&
connection[field] &&
!connection[field].startsWith('crypt:') &&
connection.passwordMode != 'saveRaw'
) {
return {
...connection,
password: 'crypt:' + getEncryptor().encrypt(connection.password),
[field]: 'crypt:' + getEncryptor().encrypt(connection[field]),
};
}
return connection;
}
function decryptConnection(connection) {
if (connection && connection.password && connection.password.startsWith('crypt:')) {
function decryptPasswordField(connection, field) {
if (connection && connection[field] && connection[field].startsWith('crypt:')) {
return {
...connection,
password: getEncryptor().decrypt(connection.password.substring('crypt:'.length)),
[field]: getEncryptor().decrypt(connection[field].substring('crypt:'.length)),
};
}
return connection;
}
function encryptConnection(connection) {
connection = encryptPasswordField(connection, 'password');
connection = encryptPasswordField(connection, 'sshPassword');
connection = encryptPasswordField(connection, 'sshKeyFilePassword');
return connection;
}
function decryptConnection(connection) {
connection = decryptPasswordField(connection, 'password');
connection = decryptPasswordField(connection, 'sshPassword');
connection = decryptPasswordField(connection, 'sshKeyFilePassword');
return connection;
}
module.exports = {
loadEncryptionKey,
encryptConnection,

View File

@@ -0,0 +1,27 @@
const fs = require('fs');
const os = require('os');
const path = require('path');
const p = process;
const platform = p.env.OS_OVERRIDE ? p.env.OS_OVERRIDE : p.platform;
const isWindows = platform === 'win32';
const isMac = platform === 'darwin';
const isLinux = platform === 'linux';
const isDocker = fs.existsSync('/home/dbgate-docker/build');
const platformInfo = {
isWindows,
isMac,
isLinux,
isDocker,
isSnap: p.env.ELECTRON_SNAP,
isPortable: isWindows && p.env.PORTABLE_EXECUTABLE_DIR,
isAppImage: p.env.DESKTOPINTEGRATION === 'AppImageLauncher',
sshAuthSock: p.env.SSH_AUTH_SOCK,
environment: process.env.NODE_ENV,
platform,
runningInWebpack: !!p.env.WEBPACK_DEV_SERVER_URL,
defaultKeyFile: path.join(os.homedir(), '.ssh/id_rsa'),
};
module.exports = platformInfo;

View File

@@ -1,7 +1,9 @@
const { SSHConnection } = require('node-ssh-forward');
const fs = require('fs-extra');
const portfinder = require('portfinder');
const stableStringify = require('json-stable-stringify');
const _ = require('lodash');
const platformInfo = require('./platformInfo');
const sshConnectionCache = {};
const sshTunnelCache = {};
@@ -16,11 +18,14 @@ async function getSshConnection(connection) {
const sshConfig = {
endHost: connection.sshHost || '',
endPort: connection.sshPort || 22,
bastionHost: '',
agentForward: false,
passphrase: undefined,
bastionHost: connection.sshBastionHost || '',
agentForward: connection.sshMode == 'agent',
passphrase: connection.sshMode == 'keyFile' ? connection.sshKeyFilePassword : undefined,
username: connection.sshLogin,
password: connection.sshPassword,
password: connection.sshMode == 'userPassword' ? connection.sshPassword : undefined,
agentSocket: connection.sshMode == 'agent' ? platformInfo.sshAuthSock : undefined,
privateKey:
connection.sshMode == 'keyFile' && connection.sshKeyFile ? await fs.readFile(connection.sshKeyFile) : undefined,
skipAutoPrivateKey: true,
noReadline: true,
};