Jelajahi Sumber

Bug 1588: Optionally display authentication banner in a monospaced font

https://winscp.net/tracker/1588

Source commit: 47a7d8bc1649823310931b2d53a0882f1318c861
Martin Prikryl 7 tahun lalu
induk
melakukan
04f0bbdc37

+ 43 - 30
source/core/Configuration.cpp

@@ -586,48 +586,61 @@ UnicodeString __fastcall TConfiguration::BannerHash(const UnicodeString & Banner
   return BytesToHex(Result);
 }
 //---------------------------------------------------------------------------
-bool __fastcall TConfiguration::ShowBanner(const UnicodeString SessionKey,
-  const UnicodeString & Banner)
+void __fastcall TConfiguration::GetBannerData(
+  const UnicodeString & SessionKey, UnicodeString & BannerHash, unsigned int & Params)
 {
-  bool Result;
-  THierarchicalStorage * Storage = CreateConfigStorage();
-  try
-  {
-    Storage->AccessMode = smRead;
-    Result =
-      !Storage->OpenSubKey(ConfigurationSubKey, false) ||
-      !Storage->OpenSubKey(L"Banners", false) ||
-      !Storage->ValueExists(SessionKey) ||
-      (Storage->ReadString(SessionKey, L"") != BannerHash(Banner));
-  }
-  __finally
+  BannerHash = UnicodeString();
+  Params = 0;
+
+  std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
+  Storage->AccessMode = smRead;
+  if (Storage->OpenSubKey(ConfigurationSubKey, false) &&
+      Storage->OpenSubKey(L"Banners", false))
   {
-    delete Storage;
+    UnicodeString S = Storage->ReadString(SessionKey, L"");
+    BannerHash = CutToChar(S, L',', true);
+    Params = StrToIntDef(L"$" + CutToChar(S, L',', true), 0);
   }
-
+}
+//---------------------------------------------------------------------------
+bool __fastcall TConfiguration::ShowBanner(
+  const UnicodeString & SessionKey, const UnicodeString & Banner, unsigned int & Params)
+{
+  UnicodeString StoredBannerHash;
+  GetBannerData(SessionKey, StoredBannerHash, Params);
+  bool Result = (StoredBannerHash != BannerHash(Banner));
   return Result;
 }
 //---------------------------------------------------------------------------
-void __fastcall TConfiguration::NeverShowBanner(const UnicodeString SessionKey,
-  const UnicodeString & Banner)
+void __fastcall TConfiguration::SetBannerData(
+  const UnicodeString & SessionKey, const UnicodeString & BannerHash, unsigned int Params)
 {
-  THierarchicalStorage * Storage = CreateConfigStorage();
-  try
-  {
-    Storage->AccessMode = smReadWrite;
+  std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
+  Storage->AccessMode = smReadWrite;
 
-    if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
-        Storage->OpenSubKey(L"Banners", true))
-    {
-      Storage->WriteString(SessionKey, BannerHash(Banner));
-    }
-  }
-  __finally
+  if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
+      Storage->OpenSubKey(L"Banners", true))
   {
-    delete Storage;
+    Storage->WriteString(SessionKey, BannerHash + L"," + UIntToStr(Params));
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TConfiguration::NeverShowBanner(const UnicodeString & SessionKey, const UnicodeString & Banner)
+{
+  UnicodeString DummyBannerHash;
+  unsigned int Params;
+  GetBannerData(SessionKey, DummyBannerHash, Params);
+  SetBannerData(SessionKey, BannerHash(Banner), Params);
+}
+//---------------------------------------------------------------------------
+void __fastcall TConfiguration::SetBannerParams(const UnicodeString & SessionKey, unsigned int Params)
+{
+  UnicodeString BannerHash;
+  unsigned int DummyParams;
+  GetBannerData(SessionKey, BannerHash, DummyParams);
+  SetBannerData(SessionKey, BannerHash, Params);
+}
+//---------------------------------------------------------------------------
 UnicodeString __fastcall TConfiguration::FormatFingerprintKey(const UnicodeString & SiteKey, const UnicodeString & FingerprintType)
 {
   return FORMAT(L"%s:%s", (SiteKey, FingerprintType));

+ 5 - 2
source/core/Configuration.h

@@ -156,6 +156,8 @@ protected:
   virtual void __fastcall Saved();
   void __fastcall CleanupRegistry(UnicodeString CleanupSubKey);
   UnicodeString __fastcall BannerHash(const UnicodeString & Banner);
+  void __fastcall SetBannerData(const UnicodeString & SessionKey, const UnicodeString & BannerHash, unsigned int Params);
+  void __fastcall GetBannerData(const UnicodeString & SessionKey, UnicodeString & BannerHash, unsigned int & Params);
   static UnicodeString __fastcall PropertyToKey(const UnicodeString & Property);
   virtual void __fastcall DoSave(bool All, bool Explicit);
   UnicodeString __fastcall FormatFingerprintKey(const UnicodeString & SiteKey, const UnicodeString & FingerprintType);
@@ -217,8 +219,9 @@ public:
     TRemoteDirectoryChangesCache * DirectoryChangesCache);
   void __fastcall SaveDirectoryChangesCache(const UnicodeString SessionKey,
     TRemoteDirectoryChangesCache * DirectoryChangesCache);
-  bool __fastcall ShowBanner(const UnicodeString SessionKey, const UnicodeString & Banner);
-  void __fastcall NeverShowBanner(const UnicodeString SessionKey, const UnicodeString & Banner);
+  bool __fastcall ShowBanner(const UnicodeString & SessionKey, const UnicodeString & Banner, unsigned int & Params);
+  void __fastcall NeverShowBanner(const UnicodeString & SessionKey, const UnicodeString & Banner);
+  void __fastcall SetBannerParams(const UnicodeString & SessionKey, unsigned int Params);
   void __fastcall RememberLastFingerprint(const UnicodeString & SiteKey, const UnicodeString & FingerprintType, const UnicodeString & Fingerprint);
   UnicodeString __fastcall LastFingerprint(const UnicodeString & SiteKey, const UnicodeString & FingerprintType);
   THierarchicalStorage * CreateConfigStorage();

+ 5 - 2
source/core/Queue.cpp

@@ -172,7 +172,7 @@ public:
   {
     if (OnDisplayBanner != NULL)
     {
-      OnDisplayBanner(Terminal, SessionName, Banner, NeverShowAgain, Options);
+      OnDisplayBanner(Terminal, SessionName, Banner, NeverShowAgain, Options, Params);
     }
   }
 
@@ -182,6 +182,7 @@ public:
   UnicodeString Banner;
   bool NeverShowAgain;
   int Options;
+  unsigned int Params;
 };
 //---------------------------------------------------------------------------
 class TReadDirectoryAction : public TUserAction
@@ -2788,7 +2789,7 @@ void __fastcall TTerminalThread::TerminalShowExtendedException(
 //---------------------------------------------------------------------------
 void __fastcall TTerminalThread::TerminalDisplayBanner(TTerminal * Terminal,
   UnicodeString SessionName, const UnicodeString & Banner,
-  bool & NeverShowAgain, int Options)
+  bool & NeverShowAgain, int Options, unsigned int & Params)
 {
   TDisplayBannerAction Action(FOnDisplayBanner);
   Action.Terminal = Terminal;
@@ -2796,10 +2797,12 @@ void __fastcall TTerminalThread::TerminalDisplayBanner(TTerminal * Terminal,
   Action.Banner = Banner;
   Action.NeverShowAgain = NeverShowAgain;
   Action.Options = Options;
+  Action.Params = Params;
 
   WaitForUserAction(&Action);
 
   NeverShowAgain = Action.NeverShowAgain;
+  Params = Action.Params;
 }
 //---------------------------------------------------------------------------
 void __fastcall TTerminalThread::TerminalChangeDirectory(TObject * Sender)

+ 1 - 1
source/core/Queue.h

@@ -437,7 +437,7 @@ private:
     Exception * E, void * Arg);
   void __fastcall TerminalDisplayBanner(TTerminal * Terminal,
     UnicodeString SessionName, const UnicodeString & Banner,
-    bool & NeverShowAgain, int Options);
+    bool & NeverShowAgain, int Options, unsigned int & Params);
   void __fastcall TerminalChangeDirectory(TObject * Sender);
   void __fastcall TerminalReadDirectory(TObject * Sender, Boolean ReloadOnly);
   void __fastcall TerminalStartReadDirectory(TObject * Sender);

+ 8 - 3
source/core/Terminal.cpp

@@ -1865,18 +1865,19 @@ void __fastcall TTerminal::DisplayBanner(const UnicodeString & Banner)
 {
   if (OnDisplayBanner != NULL)
   {
+    unsigned int OrigParams, Params;
     if (Configuration->ForceBanners ||
-        Configuration->ShowBanner(SessionData->SessionKey, Banner))
+        Configuration->ShowBanner(SessionData->SessionKey, Banner, Params))
     {
       bool NeverShowAgain = false;
       int Options =
         FLAGMASK(Configuration->ForceBanners, boDisableNeverShowAgain);
+      OrigParams = Params;
 
       TCallbackGuard Guard(this);
       try
       {
-        OnDisplayBanner(this, SessionData->SessionName, Banner,
-          NeverShowAgain, Options);
+        OnDisplayBanner(this, SessionData->SessionName, Banner, NeverShowAgain, Options, Params);
         Guard.Verify();
       }
       catch (Exception & E)
@@ -1891,6 +1892,10 @@ void __fastcall TTerminal::DisplayBanner(const UnicodeString & Banner)
       {
         Configuration->NeverShowBanner(SessionData->SessionKey, Banner);
       }
+      if (OrigParams != Params)
+      {
+        Configuration->SetBannerParams(SessionData->SessionKey, Params);
+      }
     }
   }
 }

+ 2 - 1
source/core/Terminal.h

@@ -40,7 +40,7 @@ typedef void __fastcall (__closure *TPromptUserEvent)
    TStrings * Prompts, TStrings * Results, bool & Result, void * Arg);
 typedef void __fastcall (__closure *TDisplayBannerEvent)
   (TTerminal * Terminal, UnicodeString SessionName, const UnicodeString & Banner,
-   bool & NeverShowAgain, int Options);
+   bool & NeverShowAgain, int Options, unsigned int & Params);
 typedef void __fastcall (__closure *TExtendedExceptionEvent)
   (TTerminal * Terminal, Exception * E, void * Arg);
 typedef void __fastcall (__closure *TReadDirectoryEvent)(System::TObject * Sender, Boolean ReloadOnly);
@@ -113,6 +113,7 @@ const int csIgnoreErrors = 0x01;
 const int ropNoReadDirectory = 0x02;
 //---------------------------------------------------------------------------
 const int boDisableNeverShowAgain = 0x01;
+const int bpMonospacedFont = 0x01;
 //---------------------------------------------------------------------------
 const int tfFirstLevel = 0x01;
 const int tfNewDirectory = 0x02;

+ 32 - 1
source/forms/Authenticate.cpp

@@ -370,17 +370,36 @@ bool __fastcall TAuthenticateForm::PromptUser(TPromptKind Kind, UnicodeString Na
   return Result;
 }
 //---------------------------------------------------------------------------
+void __fastcall TAuthenticateForm::UpdateBannerFont()
+{
+  if (BannerMonospacedFontAction->Checked)
+  {
+    BannerMemo->Font->Name = CustomWinConfiguration->DefaultFixedWidthFontName;
+    BannerMemo->Font->Size = CustomWinConfiguration->DefaultFixedWidthFontSize;
+  }
+  else
+  {
+    BannerMemo->ParentFont = true;
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall TAuthenticateForm::Banner(const UnicodeString & Banner,
-  bool & NeverShowAgain, int Options)
+  bool & NeverShowAgain, int Options, unsigned int & Params)
 {
   BannerMemo->Lines->Text = Banner;
   NeverShowAgainCheck->Visible = FLAGCLEAR(Options, boDisableNeverShowAgain);
   NeverShowAgainCheck->Checked = NeverShowAgain;
+  BannerMonospacedFontAction->Checked = FLAGSET(Params, bpMonospacedFont);
+  UpdateBannerFont();
+
   bool Result = Execute(LoadStr(AUTHENTICATION_BANNER), BannerPanel, BannerCloseButton,
     BannerCloseButton, BannerCloseButton, false, true, false);
   if (Result)
   {
     NeverShowAgain = NeverShowAgainCheck->Checked;
+    Params =
+      (Params & ~bpMonospacedFont) |
+      FLAGMASK(BannerMonospacedFontAction->Checked, bpMonospacedFont);
   }
 }
 //---------------------------------------------------------------------------
@@ -611,3 +630,15 @@ void __fastcall TAuthenticateForm::ChangeScale(int M, int D)
     MakeLogItemVisible(LogView->Items->Count - 1);
   }
 }
+//---------------------------------------------------------------------------
+void __fastcall TAuthenticateForm::BannerMemoContextPopup(TObject * Sender, TPoint & MousePos, bool & Handled)
+{
+  MenuPopup(Sender, MousePos, Handled);
+}
+//---------------------------------------------------------------------------
+void __fastcall TAuthenticateForm::BannerMonospacedFontActionExecute(TObject * /*Sender*/)
+{
+  BannerMonospacedFontAction->Checked = !BannerMonospacedFontAction->Checked;
+  UpdateBannerFont();
+}
+//---------------------------------------------------------------------------

+ 36 - 0
source/forms/Authenticate.dfm

@@ -236,10 +236,12 @@ object AuthenticateForm: TAuthenticateForm
       Height = 34
       Anchors = [akLeft, akTop, akRight, akBottom]
       Color = clBtnFace
+      PopupMenu = BannerPopupMenu
       ReadOnly = True
       ScrollBars = ssVertical
       TabOrder = 0
       WantReturns = False
+      OnContextPopup = BannerMemoContextPopup
     end
     object NeverShowAgainCheck: TCheckBox
       Left = 15
@@ -271,4 +273,38 @@ object AuthenticateForm: TAuthenticateForm
       OnClick = HelpButtonClick
     end
   end
+  object BannerActionList: TActionList
+    Left = 32
+    Top = 304
+    object EditCopy: TEditCopy
+      Caption = '&Copy'
+      ImageIndex = 0
+      ShortCut = 16451
+    end
+    object EditSelectAll: TEditSelectAll
+      Caption = 'Select &All'
+      ImageIndex = 1
+      ShortCut = 16449
+    end
+    object BannerMonospacedFontAction: TAction
+      Caption = 'Use &Monospaced Font'
+      OnExecute = BannerMonospacedFontActionExecute
+    end
+  end
+  object BannerPopupMenu: TPopupMenu
+    Left = 144
+    Top = 304
+    object CopyItem: TMenuItem
+      Action = EditCopy
+    end
+    object SelectAllItem: TMenuItem
+      Action = EditSelectAll
+    end
+    object N1: TMenuItem
+      Caption = '-'
+    end
+    object AdjustWindowItem: TMenuItem
+      Action = BannerMonospacedFontAction
+    end
+  end
 end

+ 18 - 1
source/forms/Authenticate.h

@@ -11,6 +11,10 @@
 #include "PasswordEdit.hpp"
 #include "WinInterface.h"
 #include "GUITools.h"
+#include <System.Actions.hpp>
+#include <Vcl.ActnList.hpp>
+#include <Vcl.Menus.hpp>
+#include <Vcl.StdActns.hpp>
 //---------------------------------------------------------------------------
 class TAuthenticateForm : public TForm
 {
@@ -39,11 +43,22 @@ __published:
   TPanel *TopPanel;
   TPanel *LeftPanel;
   TPaintBox *AnimationPaintBox;
+  TActionList *BannerActionList;
+  TEditCopy *EditCopy;
+  TEditSelectAll *EditSelectAll;
+  TAction *BannerMonospacedFontAction;
+  TPopupMenu *BannerPopupMenu;
+  TMenuItem *CopyItem;
+  TMenuItem *SelectAllItem;
+  TMenuItem *N1;
+  TMenuItem *AdjustWindowItem;
   void __fastcall FormShow(TObject *Sender);
   void __fastcall HelpButtonClick(TObject *Sender);
   void __fastcall LogViewMeasureItem(TWinControl *Control, int Index, int &Height);
   void __fastcall LogViewDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State);
   void __fastcall FormResize(TObject *Sender);
+  void __fastcall BannerMemoContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled);
+  void __fastcall BannerMonospacedFontActionExecute(TObject *Sender);
 
 public:
   __fastcall TAuthenticateForm(TComponent * Owner);
@@ -55,7 +70,7 @@ public:
   bool __fastcall PromptUser(TPromptKind Kind, UnicodeString Name, UnicodeString Instructions,
     TStrings * Prompts, TStrings * Results, bool ForceLog, bool StoredCredentialsTried);
   void __fastcall Banner(const UnicodeString & Banner, bool & NeverShowAgain,
-    int Options);
+    int Options, unsigned int & Params);
 
   __property TTerminal * Terminal = { read = FTerminal };
   __property TNotifyEvent OnCancel = { read = FOnCancel, write = FOnCancel };
@@ -79,6 +94,8 @@ protected:
   void __fastcall RedrawLog();
   void __fastcall CMShowingChanged(TMessage & Message);
   DYNAMIC void __fastcall ChangeScale(int M, int D);
+  void __fastcall UpdateBannerFont();
+  void __fastcall DoAdjustWindow();
 
 private:
   void * FShowAsModalStorage;

+ 2 - 2
source/windows/TerminalManager.cpp

@@ -1009,7 +1009,7 @@ void __fastcall TTerminalManager::TerminalPromptUser(
 //---------------------------------------------------------------------------
 void __fastcall TTerminalManager::TerminalDisplayBanner(
   TTerminal * Terminal, UnicodeString SessionName,
-  const UnicodeString & Banner, bool & NeverShowAgain, int Options)
+  const UnicodeString & Banner, bool & NeverShowAgain, int Options, unsigned int & Params)
 {
   DebugAssert(FAuthenticateForm != NULL);
   TAuthenticateForm * AuthenticateForm = FAuthenticateForm;
@@ -1020,7 +1020,7 @@ void __fastcall TTerminalManager::TerminalDisplayBanner(
 
   try
   {
-    AuthenticateForm->Banner(Banner, NeverShowAgain, Options);
+    AuthenticateForm->Banner(Banner, NeverShowAgain, Options, Params);
   }
   __finally
   {

+ 1 - 1
source/windows/TerminalManager.h

@@ -125,7 +125,7 @@ private:
     TStrings * Results, bool & Result, void * Arg);
   void __fastcall TerminalDisplayBanner(TTerminal * Terminal,
     UnicodeString SessionName, const UnicodeString & Banner, bool & NeverShowAgain,
-    int Options);
+    int Options, unsigned int & Params);
   void __fastcall TerminalShowExtendedException(TTerminal * Terminal,
     Exception * E, void * Arg);
   void __fastcall TerminalReadDirectoryProgress(TObject * Sender, int Progress,