From 0facfaa5cc28c20c3d570964b531cc2cd51ca663 Mon Sep 17 00:00:00 2001 From: Chad Whitely Date: Tue, 11 Jun 2019 12:57:20 -0700 Subject: [PATCH] Add cleartext option to sessions --- out/locale/en/LC_MESSAGES/default.po | 5 +++ source/apphelpers.pas | 8 +++-- source/connections.dfm | 13 ++++++++ source/connections.pas | 9 +++++- source/dbconnection.pas | 47 +++++++++++++++++----------- 5 files changed, 60 insertions(+), 22 deletions(-) diff --git a/out/locale/en/LC_MESSAGES/default.po b/out/locale/en/LC_MESSAGES/default.po index 8c99d03c..ffe16446 100644 --- a/out/locale/en/LC_MESSAGES/default.po +++ b/out/locale/en/LC_MESSAGES/default.po @@ -340,6 +340,11 @@ msgstr "Prompt for credentials" msgid "Use Windows authentication" msgstr "Use Windows authentication" +#. connform..PageControlDetails..tabSettings..chkCleartextPluginEnabled..Caption +#: connections.dfm:737 +msgid "Use cleartext plugin" +msgstr "Use cleartext plugin" + #. connform..PageControlDetails..tabSettings..chkLocalTimeZone....Hint #: connections.dfm:406 msgid "Use your client time zone in date/time SQL functions, e.g. NOW(), for MySQL 4.1.3+" diff --git a/source/apphelpers.pas b/source/apphelpers.pas index e306ae3a..a66a7f80 100644 --- a/source/apphelpers.pas +++ b/source/apphelpers.pas @@ -141,7 +141,7 @@ type asWrapLongLines, asDisplayBLOBsAsText, asSingleQueries, asMemoEditorWidth, asMemoEditorHeight, asMemoEditorMaximized, asMemoEditorWrap, asDelimiter, asSQLHelpWindowLeft, asSQLHelpWindowTop, asSQLHelpWindowWidth, asSQLHelpWindowHeight, asSQLHelpPnlLeftWidth, asSQLHelpPnlRightTopHeight, asHost, - asUser, asPassword, asWindowsAuth, asLoginPrompt, asPort, + asUser, asPassword, asCleartextPluginEnabled, asWindowsAuth, asLoginPrompt, asPort, asPlinkExecutable, asSSHtunnelHost, asSSHtunnelHostPort, asSSHtunnelPort, asSSHtunnelUser, asSSHtunnelPassword, asSSHtunnelTimeout, asSSHtunnelPrivateKey, asSSLActive, asSSLKey, asSSLCert, asSSLCA, asSSLCipher, asNetType, asCompressed, asLocalTimeZone, asQueryTimeout, asKeepAlive, @@ -2627,7 +2627,7 @@ var rx: TRegExpr; ExeName, SessName, Host, User, Pass, Socket, SSLPrivateKey, SSLCACertificate, SSLCertificate, SSLCipher: String; - Port, NetType, WindowsAuth, WantSSL: Integer; + Port, NetType, WindowsAuth, WantSSL, CleartextPluginEnabled: Integer; AbsentFiles: TStringList; function GetParamValue(ShortName, LongName: String): String; @@ -2692,6 +2692,7 @@ begin Host := GetParamValue('h', 'host'); User := GetParamValue('u', 'user'); Pass := GetParamValue('p', 'password'); + CleartextPluginEnabled := StrToIntDef(GetParamValue('cleartextenabled', 'cleartextenabled'), -1); Socket := GetParamValue('S', 'socket'); Port := StrToIntDef(GetParamValue('P', 'port'), 0); WindowsAuth := StrToIntDef(GetParamValue('W', 'winauth'), -1); @@ -2716,6 +2717,8 @@ begin if Host <> '' then ConnectionParams.Hostname := Host; if User <> '' then ConnectionParams.Username := User; if Pass <> '' then ConnectionParams.Password := Pass; + if CleartextPluginEnabled in [0,1] then + ConnectionParams.CleartextPluginEnabled := Boolean(CleartextPluginEnabled); if Port <> 0 then ConnectionParams.Port := Port; if Socket <> '' then begin ConnectionParams.Hostname := Socket; @@ -3521,6 +3524,7 @@ begin InitSetting(asHost, 'Host', 0, False, '127.0.0.1', True); InitSetting(asUser, 'User', 0, False, '', True); InitSetting(asPassword, 'Password', 0, False, '', True); + InitSetting(asCleartextPluginEnabled, 'CleartextPluginEnabled' 0, False, '', True); InitSetting(asWindowsAuth, 'WindowsAuth', 0, False, '', True); InitSetting(asLoginPrompt, 'LoginPrompt', 0, False, '', True); InitSetting(asPort, 'Port', 0, False, '', True); diff --git a/source/connections.dfm b/source/connections.dfm index c91ccb21..14d15af6 100644 --- a/source/connections.dfm +++ b/source/connections.dfm @@ -734,6 +734,19 @@ object connform: Tconnform TabOrder = 8 OnClick = Modification end + object chkCleartextPluginEnabled: TCheckBox + Left = 120 + Top = 329 + Width = 294 + Height = 17 + Hint = + 'Send your password to the server in cleartext' + + ', for MySQL 5.5.47+' + Anchors = [akLeft, akTop, akRight] + Caption = 'Use cleartext plugin' + TabOrder = 13 + OnClick = Modification + end object editStartupScript: TButtonedEdit Left = 120 Top = 165 diff --git a/source/connections.pas b/source/connections.pas index 5a03f39e..e4f3f0ff 100644 --- a/source/connections.pas +++ b/source/connections.pas @@ -76,6 +76,7 @@ type editSSHTimeout: TEdit; updownSSHTimeout: TUpDown; chkWindowsAuth: TCheckBox; + chkCleartextPluginEnabled: TCheckBox; splitterMain: TSplitter; tabStart: TTabSheet; lblHelp: TLabel; @@ -378,6 +379,7 @@ begin Sess.Password := editPassword.Text; Sess.LoginPrompt := chkLoginPrompt.Checked; Sess.WindowsAuth := chkWindowsAuth.Checked; + Sess.CleartextPluginEnabled := chkCleartextPluginEnabled.Checked; Sess.Port := updownPort.Position; Sess.NetType := TNetType(comboNetType.ItemIndex); Sess.Compressed := chkCompressed.Checked; @@ -574,6 +576,7 @@ begin Result.Password := editPassword.Text; Result.LoginPrompt := chkLoginPrompt.Checked; Result.WindowsAuth := chkWindowsAuth.Checked; + Result.CleartextPluginEnabled := chkCleartextPluginEnabled.Checked; if updownPort.Enabled then Result.Port := updownPort.Position else @@ -836,6 +839,7 @@ begin editPassword.Text := Sess.Password; chkLoginPrompt.Checked := Sess.LoginPrompt; chkWindowsAuth.Checked := Sess.WindowsAuth; + chkCleartextPluginEnabled.Checked := Sess.CleartextPluginEnabled; updownPort.Position := Sess.Port; chkCompressed.Checked := Sess.Compressed; updownQueryTimeout.Position := Sess.QueryTimeout; @@ -1094,6 +1098,7 @@ begin or (Sess.Username <> editUsername.Text) or (Sess.LoginPrompt <> chkLoginPrompt.Checked) or (Sess.WindowsAuth <> chkWindowsAuth.Checked) + or (Sess.CleartextPluginEnabled <> chkCleartextPluginEnabled.Checked) or (Sess.Port <> updownPort.Position) or (Sess.Compressed <> chkCompressed.Checked) or (Sess.QueryTimeout <> updownQueryTimeout.Position) @@ -1122,7 +1127,8 @@ begin FOnlyPasswordModified := PasswordModified and (not FSessionModified); FSessionModified := FSessionModified or PasswordModified; if (Sender=editHost) or (Sender=editUsername) or (Sender=editPassword) or - (Sender=comboNetType) or (Sender=chkWindowsAuth) or (Sender=editPort) then begin + (Sender=comboNetType) or (Sender=chkWindowsAuth) or (Sender=editPort) or + (Sender=chkCleartextPluginEnabled) then begin // Be sure to use the modified connection params next time the user clicks the "Databases" pulldown FreeAndNil(FPopupDatabases); end; @@ -1170,6 +1176,7 @@ begin else lblHost.Caption := _('Hostname / IP:'); chkWindowsAuth.Enabled := Params.IsMSSQL; + chkCleartextPluginEnabled.Enabled := Params.IsMySQL; lblUsername.Enabled := ((not chkLoginPrompt.Checked) or (not chkLoginPrompt.Enabled)) and ((not chkWindowsAuth.Checked) or (not chkWindowsAuth.Enabled)); editUsername.Enabled := lblUsername.Enabled; diff --git a/source/dbconnection.pas b/source/dbconnection.pas index 84bfb85b..14e555af 100644 --- a/source/dbconnection.pas +++ b/source/dbconnection.pas @@ -217,7 +217,8 @@ type FSessionPath, FSSLPrivateKey, FSSLCertificate, FSSLCACertificate, FSSLCipher, FServerVersion, FSSHHost, FSSHUser, FSSHPassword, FSSHPlinkExe, FSSHPrivateKey: String; FPort, FSSHPort, FSSHLocalPort, FSSHTimeout, FCounter, FQueryTimeout, FKeepAlive: Integer; - FLoginPrompt, FCompressed, FLocalTimeZone, FFullTableStatus, FWindowsAuth, FWantSSL, FIsFolder: Boolean; + FLoginPrompt, FCompressed, FLocalTimeZone, FFullTableStatus, + FWindowsAuth, FWantSSL, FIsFolder, FCleartextPluginEnabled: Boolean; FSessionColor: TColor; FLastConnect: TDateTime; function GetImageIndex: Integer; @@ -260,6 +261,7 @@ type property Password: String read FPassword write FPassword; property LoginPrompt: Boolean read FLoginPrompt write FLoginPrompt; property WindowsAuth: Boolean read FWindowsAuth write FWindowsAuth; + property CleartextPluginEnabled: Boolean read FCleartextPluginEnabled write FCleartextPluginEnabled; property AllDatabasesStr: String read FAllDatabases write FAllDatabases; property Comment: String read FComment write FComment; property StartupScriptFilename: String read FStartupScriptFilename write FStartupScriptFilename; @@ -1127,6 +1129,7 @@ begin FHostname := AppSettings.GetDefaultString(asHost); FLoginPrompt := AppSettings.GetDefaultBool(asLoginPrompt); FWindowsAuth := AppSettings.GetDefaultBool(asWindowsAuth); + FCleartextPluginEnabled := AppSettings.GetDefaultBool(asCleartextPluginEnabled); FUsername := DefaultUsername; FPassword := AppSettings.GetDefaultString(asPassword); FPort := DefaultPort; @@ -1194,6 +1197,7 @@ begin FPassword := decrypt(AppSettings.ReadString(asPassword)); FLoginPrompt := AppSettings.ReadBool(asLoginPrompt); FWindowsAuth := AppSettings.ReadBool(asWindowsAuth); + FCleartextPluginEnabled := AppSettings.ReadBool(asCleartextPluginEnabled); FPort := MakeInt(AppSettings.ReadString(asPort)); FCompressed := AppSettings.ReadBool(asCompressed); FAllDatabases := AppSettings.ReadString(asDatabases); @@ -1249,6 +1253,7 @@ begin else begin AppSettings.WriteString(asHost, FHostname); AppSettings.WriteBool(asWindowsAuth, FWindowsAuth); + AppSettings.WriteBool(asCleartextPluginEnabled, FCleartextPluginEnabled); AppSettings.WriteString(asUser, FUsername); AppSettings.WriteString(asPassword, encrypt(FPassword)); AppSettings.WriteBool(asLoginPrompt, FLoginPrompt); @@ -1825,6 +1830,10 @@ begin mysql_options(FHandle, Integer(MARIADB_OPT_TLS_VERSION), PAnsiChar('TLSv1,TLSv1.1,TLSv1.2,TLSv1.3')); mysql_options(FHandle, Integer(MYSQL_OPT_TLS_VERSION), PAnsiChar('TLSv1,TLSv1.1,TLSv1.2,TLSv1.3')); + // Enable cleartext plugin + if Parameters.CleartextPluginEnabled then + mysql_options(FHandle, MYSQL_ENABLE_CLEARTEXT_PLUGIN, 1); + Connected := mysql_real_connect( FHandle, PAnsiChar(Utf8Encode(FinalHost)), @@ -5046,24 +5055,24 @@ begin if rx.Exec(SQL) then begin LeftQuote := rx.Match[0]; LeftPos := rx.MatchPos[0] + 1; - - // Step forward for each character of the identifier - i := LeftPos; - RightPos := LeftPos; - while i < Length(SQL) do begin - if SQL[i] = LeftQuote then begin - if SQL[i+1] = SQL[i] then // take doubled/escaped quote char into account - Inc(i) - else begin - RightPos := i; - Break; - end; - end; - Result := Result + SQL[i]; - Inc(i); - end; - - if RightPos > LeftPos then + + // Step forward for each character of the identifier + i := LeftPos; + RightPos := LeftPos; + while i < Length(SQL) do begin + if SQL[i] = LeftQuote then begin + if SQL[i+1] = SQL[i] then // take doubled/escaped quote char into account + Inc(i) + else begin + RightPos := i; + Break; + end; + end; + Result := Result + SQL[i]; + Inc(i); + end; + + if RightPos > LeftPos then Delete(SQL, 1, RightPos+1); end; end;