Skip to content
Permalink
Browse files

Add support for SSH tunneled PostgreSQL connections. See issue #78

  • Loading branch information...
ansgarbecker committed May 14, 2019
1 parent 927e144 commit f893a8de751e55ce3d6db7f3ff27a6847134d09c
Showing with 33 additions and 10 deletions.
  1. +2 −2 source/connections.pas
  2. +31 −8 source/dbconnection.pas
@@ -1179,7 +1179,7 @@ procedure Tconnform.ValidateControls;
editUsername.Enabled := lblUsername.Enabled;
lblPassword.Enabled := lblUsername.Enabled;
editPassword.Enabled := lblUsername.Enabled;
lblPort.Enabled := Params.NetType in [ntMySQL_TCPIP, ntMySQL_SSHtunnel, ntMSSQL_TCPIP, ntPgSQL_TCPIP];
lblPort.Enabled := Params.NetType in [ntMySQL_TCPIP, ntMySQL_SSHtunnel, ntMSSQL_TCPIP, ntPgSQL_TCPIP, ntPgSQL_SSHtunnel];
if (Params.NetType = ntMSSQL_TCPIP) and (Pos('\', editHost.Text) > 0) then
lblPort.Enabled := False; // Named instance without port
editPort.Enabled := lblPort.Enabled;
@@ -1197,7 +1197,7 @@ procedure Tconnform.ValidateControls;
editSSLCertificate.Enabled := Params.WantSSL;
lblSSLcipher.Enabled := Params.WantSSL;
editSSLcipher.Enabled := Params.WantSSL;
tabSSHtunnel.TabVisible := Params.NetType = ntMySQL_SSHtunnel;
tabSSHtunnel.TabVisible := Params.NetType in [ntMySQL_SSHtunnel, ntPgSQL_SSHtunnel];
lblQueryTimeout.Enabled := Params.NetTypeGroup in [ngMSSQL, ngPgSQL];
editQueryTimeout.Enabled := lblQueryTimeout.Enabled;
updownQueryTimeout.Enabled := lblQueryTimeout.Enabled;
@@ -205,7 +205,7 @@ TPlink = class(TObject)

TNetType = (ntMySQL_TCPIP, ntMySQL_NamedPipe, ntMySQL_SSHtunnel,
ntMSSQL_NamedPipe, ntMSSQL_TCPIP, ntMSSQL_SPX, ntMSSQL_VINES, ntMSSQL_RPC,
ntPgSQL_TCPIP);
ntPgSQL_TCPIP, ntPgSQL_SSHtunnel);
TNetTypeGroup = (ngMySQL, ngMSSQL, ngPgSQL);

TConnectionParameters = class(TObject)
@@ -304,6 +304,7 @@ TDBConnection = class(TComponent)
FServerUptime: Integer;
FServerDateTimeOnStartup: String;
FParameters: TConnectionParameters;
FPlink: TPlink;
FLoginPromptDone: Boolean;
FDatabase: String;
FAllDatabases: TStringList;
@@ -469,7 +470,6 @@ TMySQLConnection = class(TDBConnection)
private
FHandle: PMYSQL;
FLastRawResults: TMySQLRawResults;
FPlink: TPlink;
procedure SetActive(Value: Boolean); override;
procedure DoBeforeConnect; override;
procedure DoAfterConnect; override;
@@ -1342,13 +1342,15 @@ function TConnectionParameters.NetTypeName(NetType: TNetType; LongFormat: Boolea
ntMSSQL_RPC:
Result := 'Microsoft SQL Server (Windows RPC)';
ntPgSQL_TCPIP:
Result := 'PostgreSQL ('+_('experimental')+')';
Result := 'PostgreSQL (TCP/IP)';
ntPgSQL_SSHtunnel:
Result := 'PostgreSQL (SSH tunnel)';
end else case NetType of
ntMySQL_TCPIP, ntMySQL_NamedPipe, ntMySQL_SSHtunnel:
Result := My;
ntMSSQL_NamedPipe, ntMSSQL_TCPIP:
Result := 'MS SQL';
ntPgSQL_TCPIP:
ntPgSQL_TCPIP, ntPgSQL_SSHtunnel:
Result := 'PostgreSQL';
end;
end;
@@ -1357,7 +1359,7 @@ function TConnectionParameters.NetTypeName(NetType: TNetType; LongFormat: Boolea
class function TConnectionParameters.IsCompatibleToWin10S(NetType: TNetType): Boolean;
begin
// Using plink on 10S is not possible
Result := NetType <> ntMySQL_SSHtunnel;
Result := (NetType <> ntMySQL_SSHtunnel) and (NetType <> ntPgSQL_SSHtunnel);
end;


@@ -1368,7 +1370,7 @@ function TConnectionParameters.GetNetTypeGroup: TNetTypeGroup;
Result := ngMySQL;
ntMSSQL_NamedPipe, ntMSSQL_TCPIP, ntMSSQL_SPX, ntMSSQL_VINES, ntMSSQL_RPC:
Result := ngMSSQL;
ntPgSQL_TCPIP:
ntPgSQL_TCPIP, ntPgSQL_SSHtunnel:
Result := ngPgSQL;
else
raise Exception.CreateFmt(_(MsgUnhandledNetType), [Integer(FNetType)]);
@@ -2072,6 +2074,8 @@ procedure TAdoDBConnection.SetActive(Value: Boolean);
procedure TPgConnection.SetActive(Value: Boolean);
var
dbname, ConnInfo, Error, tmpdb: String;
FinalHost: String;
FinalPort: Integer;
begin
if Value then begin
DoBeforeConnect;
@@ -2080,8 +2084,23 @@ procedure TPgConnection.SetActive(Value: Boolean);
dbname := FParameters.AllDatabasesStr;
if dbname = '' then
dbname := 'postgres';
ConnInfo := 'host='''+FParameters.Hostname+''' '+
'port='''+IntToStr(FParameters.Port)+''' '+

// Prepare special stuff for SSH tunnel
FinalHost := FParameters.Hostname;
FinalPort := FParameters.Port;

case FParameters.NetType of
ntPgSQL_SSHtunnel: begin
// Create plink.exe process
FPlink := TPlink.Create(Self);
FPlink.Connect;
FinalHost := '127.0.0.1';
FinalPort := FParameters.SSHLocalPort;
end;
end;

ConnInfo := 'host='''+FinalHost+''' '+
'port='''+IntToStr(FinalPort)+''' '+
'user='''+FParameters.Username+''' ' +
'password='''+FParameters.Password+''' '+
'dbname='''+dbname+''' '+
@@ -2093,6 +2112,8 @@ procedure TPgConnection.SetActive(Value: Boolean);
FConnectionStarted := 0;
PQfinish(FHandle); // free the memory
FHandle := nil;
if FPlink <> nil then
FPlink.Free;
raise EDatabaseError.Create(Error);
end;
FActive := True;
@@ -2129,6 +2150,8 @@ procedure TPgConnection.SetActive(Value: Boolean);
FActive := False;
ClearCache(False);
FConnectionStarted := 0;
if FPlink <> nil then
FPlink.Free;
Log(lcInfo, f_(MsgDisconnect, [FParameters.Hostname, DateTimeToStr(Now)]));
end;
end;

0 comments on commit f893a8d

Please sign in to comment.
You can’t perform that action at this time.