Issue #401: Extend SSH tunnel options: Allow user to set SHH host/ip and port, and a private key file used for authentication. If SSH host is not set, use what the user specified as MySQL server host.

This commit is contained in:
Ansgar Becker
2010-04-01 23:34:07 +00:00
parent 7e80d8dd34
commit adf68ecc65
5 changed files with 157 additions and 36 deletions

View File

@ -275,7 +275,7 @@ object connform: Tconnform
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
OnChange = Modification
OnChange = editHostChange
end
object comboNetType: TComboBox
Left = 101
@ -300,28 +300,28 @@ object connform: Tconnform
DesignSize = (
301
197)
object lblSSHPort: TLabel
object lblSSHLocalPort: TLabel
Left = 3
Top = 39
Top = 163
Width = 51
Height = 13
Caption = 'Local port:'
FocusControl = editSSHPort
FocusControl = editSSHlocalport
end
object lblSSHUser: TLabel
Left = 3
Top = 66
Width = 76
Top = 82
Width = 52
Height = 13
Caption = 'Shell username:'
Caption = 'Username:'
FocusControl = editSSHUser
end
object lblSSHPassword: TLabel
Left = 3
Top = 93
Width = 75
Top = 109
Width = 50
Height = 13
Caption = 'Shell password:'
Caption = 'Password:'
FocusControl = editSSHPassword
end
object lblSSHPlinkExe: TLabel
@ -331,35 +331,67 @@ object connform: Tconnform
Height = 13
Caption = 'plink.exe location:'
end
object editSSHPort: TEdit
object lblSSHhost: TLabel
Left = 3
Top = 55
Width = 81
Height = 13
Caption = 'SSH host + port:'
FocusControl = editSSHhost
end
object lblSSHkeyfile: TLabel
Left = 3
Top = 136
Width = 75
Height = 13
Caption = 'Private key file:'
FocusControl = editSSHPrivateKey
end
object lblDownloadPlink: TLabel
Left = 101
Top = 36
Top = 33
Width = 93
Height = 13
Cursor = crHandPoint
Hint = 'http://putty.very.rulez.org/latest/x86/plink.exe'
Caption = 'Download plink.exe'
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = [fsUnderline]
ParentFont = False
OnClick = lblDownloadPlinkClick
end
object editSSHlocalport: TEdit
Left = 101
Top = 160
Width = 188
Height = 21
Anchors = [akLeft, akTop, akRight]
NumbersOnly = True
TabOrder = 0
Text = 'editSSHPort'
TabOrder = 6
Text = 'editSSHlocalport'
OnChange = Modification
end
object editSSHUser: TEdit
Left = 101
Top = 63
Top = 79
Width = 188
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 1
TabOrder = 3
Text = 'editSSHUser'
OnChange = Modification
end
object editSSHPassword: TEdit
Left = 101
Top = 90
Top = 106
Width = 188
Height = 21
Anchors = [akLeft, akTop, akRight]
PasswordChar = '*'
TabOrder = 2
TabOrder = 4
Text = 'editSSHPassword'
OnChange = Modification
end
@ -372,12 +404,48 @@ object connform: Tconnform
Images = MainForm.ImageListMain
RightButton.ImageIndex = 51
RightButton.Visible = True
TabOrder = 3
TabOrder = 0
Text = 'editSSHPlinkExe'
OnChange = editSSHPlinkExeChange
OnDblClick = PickFile
OnRightButtonClick = PickFile
end
object editSSHhost: TEdit
Left = 101
Top = 52
Width = 133
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 1
Text = 'editSSHhost'
OnChange = Modification
end
object editSSHport: TEdit
Left = 240
Top = 52
Width = 49
Height = 21
Anchors = [akTop, akRight]
NumbersOnly = True
TabOrder = 2
Text = 'editSSHport'
OnChange = Modification
end
object editSSHPrivateKey: TButtonedEdit
Left = 101
Top = 133
Width = 188
Height = 21
Anchors = [akLeft, akTop, akRight]
Images = MainForm.ImageListMain
RightButton.ImageIndex = 51
RightButton.Visible = True
TabOrder = 5
Text = 'editSSHPrivateKey'
OnChange = Modification
OnDblClick = PickFile
OnRightButtonClick = PickFile
end
end
object tabSSLOptions: TTabSheet
Caption = 'SSL options'

View File

@ -58,15 +58,21 @@ type
lblCounterRight: TLabel;
lblLastConnectRight: TLabel;
tabSSHtunnel: TTabSheet;
editSSHPort: TEdit;
editSSHlocalport: TEdit;
editSSHUser: TEdit;
editSSHPassword: TEdit;
lblSSHPort: TLabel;
lblSSHLocalPort: TLabel;
lblSSHUser: TLabel;
lblSSHPassword: TLabel;
editSSHPlinkExe: TButtonedEdit;
lblSSHPlinkExe: TLabel;
comboNetType: TComboBox;
lblSSHhost: TLabel;
editSSHhost: TEdit;
editSSHport: TEdit;
editSSHPrivateKey: TButtonedEdit;
lblSSHkeyfile: TLabel;
lblDownloadPlink: TLabel;
procedure FormCreate(Sender: TObject);
procedure btnOpenClick(Sender: TObject);
procedure FormShow(Sender: TObject);
@ -99,6 +105,8 @@ type
procedure FormResize(Sender: TObject);
procedure PickFile(Sender: TObject);
procedure editSSHPlinkExeChange(Sender: TObject);
procedure editHostChange(Sender: TObject);
procedure lblDownloadPlinkClick(Sender: TObject);
private
{ Private declarations }
FLoaded: Boolean;
@ -200,9 +208,12 @@ begin
Params.Username := editUsername.Text;
Params.Password := editPassword.Text;
Params.Port := MakeInt(editPort.Text);
Params.SSHHost := editSSHHost.Text;
Params.SSHPort := MakeInt(editSSHPort.Text);
Params.SSHUser := editSSHuser.Text;
Params.SSHPassword := editSSHpassword.Text;
Params.SSHPort := MakeInt(editSSHport.Text);
Params.SSHPrivateKey := editSSHPrivateKey.Text;
Params.SSHLocalPort := MakeInt(editSSHlocalport.Text);
Params.SSHPlinkExe := editSSHplinkexe.Text;
Params.SSLPrivateKey := editSSLPrivateKey.Text;
Params.SSLCertificate := editSSLCertificate.Text;
@ -232,9 +243,12 @@ begin
MainReg.WriteInteger(REGNAME_NETTYPE, comboNetType.ItemIndex);
MainReg.WriteBool(REGNAME_COMPRESSED, chkCompressed.Checked);
MainReg.WriteString(REGNAME_STARTUPSCRIPT, editStartupScript.Text);
MainReg.WriteInteger(REGNAME_SSHPORT, MakeInt(editSSHPort.Text));
MainReg.WriteString(REGNAME_SSHHOST, editSSHHost.Text);
MainReg.WriteInteger(REGNAME_SSHPORT, MakeInt(editSSHport.Text));
MainReg.WriteString(REGNAME_SSHUSER, editSSHUser.Text);
MainReg.WriteString(REGNAME_SSHPASSWORD, encrypt(editSSHPassword.Text));
MainReg.WriteString(REGNAME_SSHKEY, editSSHPrivateKey.Text);
MainReg.WriteInteger(REGNAME_SSHLOCALPORT, MakeInt(editSSHlocalport.Text));
MainReg.WriteString(REGNAME_SSL_KEY, editSSLPrivateKey.Text);
MainReg.WriteString(REGNAME_SSL_CERT, editSSLCertificate.Text);
MainReg.WriteString(REGNAME_SSL_CA, editSSLCACertificate.Text);
@ -415,9 +429,12 @@ begin
chkCompressed.Checked := opCompress in FOrgParams.Options;
editStartupScript.Text := FOrgParams.StartupScriptFilename;
editSSHPlinkExe.Text := FOrgParams.SSHPlinkExe;
editSSHPort.Text := IntToStr(FOrgParams.SSHPort);
editSSHHost.Text := FOrgParams.SSHHost;
editSSHport.Text := IntToStr(FOrgParams.SSHPort);
editSSHUser.Text := FOrgParams.SSHUser;
editSSHPassword.Text := FOrgParams.SSHPassword;
editSSHPrivateKey.Text := FOrgParams.SSHPrivateKey;
editSSHlocalport.Text := IntToStr(FOrgParams.SSHLocalPort);
editSSLPrivateKey.Text := FOrgParams.SSLPrivateKey;
editSSLCertificate.Text := FOrgParams.SSLCertificate;
editSSLCACertificate.Text := FOrgParams.SSLCACertificate;
@ -530,6 +547,12 @@ begin
end;
procedure Tconnform.editHostChange(Sender: TObject);
begin
editSSHhost.TextHint := TEdit(Sender).Text;
Modification(Sender);
end;
procedure Tconnform.editPortChange(Sender: TObject);
begin
// Work around smallint values of TUpDown, allow integer values
@ -551,7 +574,7 @@ begin
or (FOrgParams.NetType <> TNetType(comboNetType.ItemIndex))
or (FOrgParams.StartupScriptFilename <> editStartupScript.Text)
or (FOrgParams.SSHPlinkExe <> editSSHPlinkExe.Text)
or (IntToStr(FOrgParams.SSHPort) <> editSSHPort.Text)
or (IntToStr(FOrgParams.SSHLocalPort) <> editSSHlocalport.Text)
or (FOrgParams.SSHUser <> editSSHUser.Text)
or (FOrgParams.SSHPassword <> editSSHPassword.Text)
or (FOrgParams.SSLPrivateKey <> editSSLPrivateKey.Text)
@ -692,4 +715,10 @@ begin
end;
procedure Tconnform.lblDownloadPlinkClick(Sender: TObject);
begin
ShellExec(TLabel(Sender).Hint);
end;
end.

View File

@ -123,9 +123,13 @@ const
REGNAME_PORT = 'Port';
DEFAULT_PORT = 3306;
REGNAME_PLINKEXE = 'PlinkExecutable';
REGNAME_SSHPORT = 'SSHtunnelPort';
REGNAME_SSHHOST = 'SSHtunnelHost';
REGNAME_SSHPORT = 'SSHtunnelHostPort';
DEFAULT_SSHPORT = 22;
REGNAME_SSHLOCALPORT = 'SSHtunnelPort';
REGNAME_SSHUSER = 'SSHtunnelUser';
REGNAME_SSHPASSWORD = 'SSHtunnelPassword';
REGNAME_SSHKEY = 'SSHtunnelPrivateKey';
REGNAME_SSL_KEY = 'SSL_Key';
REGNAME_SSL_CERT = 'SSL_Cert';
REGNAME_SSL_CA = 'SSL_CA';

View File

@ -3608,9 +3608,12 @@ begin
Result.Username := GetRegValue(REGNAME_USER, '', Session);
Result.Password := decrypt(GetRegValue(REGNAME_PASSWORD, '', Session));
Result.Port := StrToIntDef(GetRegValue(REGNAME_PORT, '', Session), DEFAULT_PORT);
Result.SSHHost := GetRegValue(REGNAME_SSHHOST, '', Session);
Result.SSHPort := GetRegValue(REGNAME_SSHPORT, DEFAULT_SSHPORT, Session);
Result.SSHUser := GetRegValue(REGNAME_SSHUSER, '', Session);
Result.SSHPassword := decrypt(GetRegValue(REGNAME_SSHPASSWORD, '', Session));
Result.SSHPort := GetRegValue(REGNAME_SSHPORT, 0, Session);
Result.SSHPrivateKey := GetRegValue(REGNAME_SSHKEY, '', Session);
Result.SSHLocalPort := GetRegValue(REGNAME_SSHLOCALPORT, 0, Session);
Result.SSHPlinkExe := GetRegValue(REGNAME_PLINKEXE, '');
Result.SSLPrivateKey := GetRegValue(REGNAME_SSL_KEY, '', Session);
Result.SSLCertificate := GetRegValue(REGNAME_SSL_CERT, '', Session);

View File

@ -58,8 +58,8 @@ type
FNetType: TNetType;
FHostname, FUsername, FPassword, FStartupScriptFilename,
FSSLPrivateKey, FSSLCertificate, FSSLCACertificate,
FSSHUser, FSSHPassword, FSSHPlinkExe: String;
FPort, FSSHPort: Integer;
FSSHHost, FSSHUser, FSSHPassword, FSSHPlinkExe, FSSHPrivateKey: String;
FPort, FSSHPort, FSSHLocalPort: Integer;
FOptions: TMySQLClientOptions;
public
constructor Create;
@ -71,9 +71,12 @@ type
property Password: String read FPassword write FPassword;
property StartupScriptFilename: String read FStartupScriptFilename write FStartupScriptFilename;
property Options: TMySQLClientOptions read FOptions write FOptions;
property SSHHost: String read FSSHHost write FSSHHost;
property SSHPort: Integer read FSSHPort write FSSHPort;
property SSHUser: String read FSSHUser write FSSHUser;
property SSHPassword: String read FSSHPassword write FSSHPassword;
property SSHPort: Integer read FSSHPort write FSSHPort;
property SSHPrivateKey: String read FSSHPrivateKey write FSSHPrivateKey;
property SSHLocalPort: Integer read FSSHLocalPort write FSSHLocalPort;
property SSHPlinkExe: String read FSSHPlinkExe write FSSHPlinkExe;
property SSLPrivateKey: String read FSSLPrivateKey write FSSLPrivateKey;
property SSLCertificate: String read FSSLCertificate write FSSLCertificate;
@ -243,6 +246,8 @@ begin
FUsername := DEFAULT_USER;
FPassword := '';
FPort := DEFAULT_PORT;
FSSHPort := DEFAULT_SSHPORT;
FSSHLocalPort := FPort + 1;
FSSLPrivateKey := '';
FSSLCertificate := '';
FSSLCACertificate := '';
@ -334,11 +339,23 @@ begin
end;
ntSSHtunnel: begin
// Call plink.exe
// plink bob@domain.com -pw myPassw0rd1 -L 55555:localhost:3306
PlinkCmd := FParameters.SSHPlinkExe + ' ' + FParameters.SSHUser + '@' + FParameters.Hostname +
' -pw ' + FParameters.SSHPassword +
' -L ' + IntToStr(FParameters.SSHPort) + ':localhost:' + IntToStr(FParameters.Port);
// Build plink.exe command line
// plink bob@domain.com -pw myPassw0rd1 -P 22 -i "keyfile.pem" -L 55555:localhost:3306
PlinkCmd := FParameters.SSHPlinkExe + ' ';
if FParameters.SSHUser <> '' then
PlinkCmd := PlinkCmd + FParameters.SSHUser + '@';
if FParameters.SSHHost <> '' then
PlinkCmd := PlinkCmd + FParameters.SSHHost
else
PlinkCmd := PlinkCmd + FParameters.Hostname;
if FParameters.SSHPassword <> '' then
PlinkCmd := PlinkCmd + ' -pw ' + FParameters.SSHPassword;
PlinkCmd := PlinkCmd + ' -P ' + IntToStr(FParameters.SSHPort);
if FParameters.SSHPrivateKey <> '' then
PlinkCmd := PlinkCmd + ' -i "' + FParameters.SSHPrivateKey + '"';
PlinkCmd := PlinkCmd + ' -L ' + IntToStr(FParameters.SSHLocalPort) + ':' + FParameters.Hostname + ':' + IntToStr(FParameters.Port);
log(lcInfo, PlinkCmd);
// Create plink.exe process
FillChar(FPlinkProcInfo, SizeOf(TProcessInformation), 0);
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
StartupInfo.cb := SizeOf(TStartupInfo);
@ -354,7 +371,7 @@ begin
raise Exception.Create('Couldn''t execute PLink: '+CRLF+PlinkCmd);
end;
FinalHost := 'localhost';
FinalPort := FParameters.SSHPort;
FinalPort := FParameters.SSHLocalPort;
end;
end;