diff --git a/source/connections.dfm b/source/connections.dfm index 975c04fa..4f4543b1 100644 --- a/source/connections.dfm +++ b/source/connections.dfm @@ -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' diff --git a/source/connections.pas b/source/connections.pas index a4ba3b92..8e59fcf3 100644 --- a/source/connections.pas +++ b/source/connections.pas @@ -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. diff --git a/source/const.inc b/source/const.inc index fd30e68e..0087a987 100644 --- a/source/const.inc +++ b/source/const.inc @@ -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'; diff --git a/source/helpers.pas b/source/helpers.pas index f5d2413a..157299b4 100644 --- a/source/helpers.pas +++ b/source/helpers.pas @@ -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); diff --git a/source/mysql_connection.pas b/source/mysql_connection.pas index 1538cd63..40752e4e 100644 --- a/source/mysql_connection.pas +++ b/source/mysql_connection.pas @@ -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;