mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
SSL support
This commit is contained in:
parent
417ec9fcd2
commit
d08fc85459
@ -1,45 +1,54 @@
|
||||
const { SSHConnection } = require('node-ssh-forward');
|
||||
const portfinder = require('portfinder');
|
||||
const fs = require('fs-extra');
|
||||
const { decryptConnection } = require('./crypting');
|
||||
const { getSshTunnel } = require('./sshTunnel');
|
||||
const { getSshTunnelProxy } = require('./sshTunnelProxy');
|
||||
|
||||
async function connectUtility(driver, storedConnection) {
|
||||
let connection = decryptConnection(storedConnection);
|
||||
const connection = {
|
||||
...decryptConnection(storedConnection),
|
||||
};
|
||||
if (connection.useSshTunnel) {
|
||||
const tunnel = await getSshTunnelProxy(connection);
|
||||
if (tunnel.state == 'error') {
|
||||
throw new Error(tunnel.message);
|
||||
}
|
||||
// const sshConfig = {
|
||||
// endHost: connection.sshHost || '',
|
||||
// endPort: connection.sshPort || 22,
|
||||
// bastionHost: '',
|
||||
// agentForward: false,
|
||||
// passphrase: undefined,
|
||||
// username: connection.sshLogin,
|
||||
// password: connection.sshPassword,
|
||||
// skipAutoPrivateKey: true,
|
||||
// noReadline: true,
|
||||
// };
|
||||
|
||||
// const sshConn = new SSHConnection(sshConfig);
|
||||
// const localPort = await portfinder.getPortPromise({ port: 10000, stopPort: 60000 });
|
||||
// // workaround for `getPortPromise` not releasing the port quickly enough
|
||||
// await new Promise(resolve => setTimeout(resolve, 500));
|
||||
// const tunnelConfig = {
|
||||
// fromPort: localPort,
|
||||
// toPort: connection.port,
|
||||
// toHost: connection.server,
|
||||
// };
|
||||
// const tunnel = await sshConn.forward(tunnelConfig);
|
||||
// console.log(`Created SSH tunnel to ${connection.sshHost}-${connection.server}:${connection.port}, using local port ${localPort}`)
|
||||
connection.server = '127.0.0.1';
|
||||
connection.port = tunnel.localPort;
|
||||
}
|
||||
|
||||
connection = {
|
||||
...connection,
|
||||
server: '127.0.0.1',
|
||||
port: tunnel.localPort,
|
||||
};
|
||||
if (!connection.port && driver.defaultPort) connection.port = driver.defaultPort.toString();
|
||||
|
||||
// SSL functionality - copied from https://github.com/beekeeper-studio/beekeeper-studio
|
||||
if (connection.useSsl) {
|
||||
connection.ssl = {};
|
||||
|
||||
if (connection.sslCaFile) {
|
||||
connection.ssl.ca = await fs.readFile(connection.sslCaFile);
|
||||
}
|
||||
|
||||
if (connection.sslCertFile) {
|
||||
connection.ssl.cert = await fs.readFile(connection.sslCertFile);
|
||||
}
|
||||
|
||||
if (connection.sslKeyFile) {
|
||||
connection.ssl.key = await fs.readFile(connection.sslKeyFile);
|
||||
}
|
||||
|
||||
if (!connection.ssl.key && !connection.ssl.ca && !connection.ssl.cert) {
|
||||
// TODO: provide this as an option in settings
|
||||
// or per-connection as 'reject self-signed certs'
|
||||
// How it works:
|
||||
// if false, cert can be self-signed
|
||||
// if true, has to be from a public CA
|
||||
// Heroku certs are self-signed.
|
||||
// if you provide ca/cert/key files, it overrides this
|
||||
connection.ssl.rejectUnauthorized = false;
|
||||
} else {
|
||||
connection.ssl.rejectUnauthorized = connection.sslRejectUnauthorized;
|
||||
}
|
||||
}
|
||||
|
||||
const conn = await driver.connect(connection);
|
||||
|
@ -98,6 +98,7 @@ function DriverFields({ extensions }) {
|
||||
name="port"
|
||||
disabled={disabledFields.includes('port')}
|
||||
templateProps={{ noMargin: true }}
|
||||
placeholder={driver && driver.defaultPort}
|
||||
/>
|
||||
</FlexCol3>
|
||||
</FormRowLarge>
|
||||
@ -235,6 +236,22 @@ function SshTunnelFields() {
|
||||
);
|
||||
}
|
||||
|
||||
function SslFields() {
|
||||
const { values } = useForm();
|
||||
const { useSsl } = values;
|
||||
const electron = getElectron();
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormCheckboxField label="Use SSL" name="useSsl" />
|
||||
<FormElectronFileSelector label="CA Cert (optional)" name="sslCaFile" disabled={!useSsl || !electron} />
|
||||
<FormElectronFileSelector label="Certificate (optional)" name="sslCertFile" disabled={!useSsl || !electron} />
|
||||
<FormElectronFileSelector label="Key file (optional)" name="sslKeyFile" disabled={!useSsl || !electron} />
|
||||
<FormCheckboxField label="Reject unauthorized" name="sslRejectUnauthorized" disabled={!useSsl} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ConnectionModal({ modalState, connection = undefined }) {
|
||||
const [sqlConnectResult, setSqlConnectResult] = React.useState(null);
|
||||
const extensions = useExtensions();
|
||||
@ -288,6 +305,9 @@ export default function ConnectionModal({ modalState, connection = undefined })
|
||||
<TabPage label="SSH Tunnel" key="sshTunnel">
|
||||
<SshTunnelFields />
|
||||
</TabPage>
|
||||
<TabPage label="SSL" key="ssl">
|
||||
<SslFields />
|
||||
</TabPage>
|
||||
</TabControl>
|
||||
</ModalContent>
|
||||
|
||||
|
@ -119,7 +119,7 @@ export function FormCheckboxField({ label, templateProps = undefined, ...other }
|
||||
<FieldTemplate
|
||||
label={label}
|
||||
type="checkbox"
|
||||
onLabelClick={() => setFieldValue(other.name, !values[other.name])}
|
||||
onLabelClick={other.disabled ? undefined : () => setFieldValue(other.name, !values[other.name])}
|
||||
{...templateProps}
|
||||
>
|
||||
<FormCheckboxFieldRaw {...other} />
|
||||
|
Loading…
Reference in New Issue
Block a user