Browse Source

Bug 386: Added Generate button to Authentication page of Advanced Site Settings dialog that starts PuTTYgen and detects a private key file generated by it

https://winscp.net/tracker/386

Source commit: 7f9a09e18ee983dce3eb2490eaaf541620ad5452
Martin Prikryl 7 years ago
parent
commit
bc9622ab93

+ 1 - 0
source/core/PuttyIntf.cpp

@@ -29,6 +29,7 @@ const UnicodeString OriginalPuttyRegistryStorageKey(_T(PUTTY_REG_POS));
 const UnicodeString KittyRegistryStorageKey(L"Software\\9bis.com\\KiTTY");
 const UnicodeString OriginalPuttyExecutable("putty.exe");
 const UnicodeString KittyExecutable("kitty.exe");
+const UnicodeString PuttyKeyExt(L"ppk");
 //---------------------------------------------------------------------------
 void __fastcall PuttyInitialize()
 {

+ 1 - 0
source/core/PuttyTools.h

@@ -17,6 +17,7 @@ void ChangeKeyComment(TPrivateKey * PrivateKey, const UnicodeString & Comment);
 void SaveKey(TKeyType KeyType, const UnicodeString & FileName,
   const UnicodeString & Passphrase, TPrivateKey * PrivateKey);
 void FreeKey(TPrivateKey * PrivateKey);
+extern const UnicodeString PuttyKeyExt;
 //---------------------------------------------------------------------------
 bool __fastcall HasGSSAPI(UnicodeString CustomPath);
 //---------------------------------------------------------------------------

+ 1 - 23
source/forms/CustomScpExplorer.cpp

@@ -6735,29 +6735,7 @@ void __fastcall TCustomScpExplorerForm::DDFakeFileInitDrag(TFileList * FileList,
 
   if (!WinConfiguration->IsDDExtRunning())
   {
-    FDragFakeMonitors = new TObjectList();
-    for (char Drive = FirstDrive; Drive <= LastDrive; Drive++)
-    {
-      std::unique_ptr<TDirectoryMonitor> Monitor(new TDirectoryMonitor(this));
-      TDriveInfoRec * DriveInfoRec = DriveInfo->Get(Drive);
-      if (DriveInfoRec->Valid &&
-          (DriveInfoRec->DriveType != DRIVE_CDROM))
-      {
-        try
-        {
-          Monitor->Path = DriveInfo->GetDriveRoot(Drive);
-          Monitor->WatchSubtree = true;
-          Monitor->WatchFilters = FILE_NOTIFY_CHANGE_DIR_NAME;
-          Monitor->OnCreated = DDFakeCreated;
-          Monitor->Active = true;
-          FDragFakeMonitors->Add(Monitor.release());
-        }
-        catch (Exception & E)
-        {
-          // Ignore errors watching not-ready drives
-        }
-      }
-    }
+    FDragFakeMonitors = StartCreationDirectoryMonitorsOnEachDrive(FILE_NOTIFY_CHANGE_DIR_NAME, DDFakeCreated);
   }
 
   FDDExtMapFile = CreateFileMappingA((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE,

+ 0 - 11
source/forms/Login.cpp

@@ -2429,17 +2429,6 @@ void __fastcall TLoginDialog::SessionTreeExpanding(TObject * /*Sender*/,
   AllowExpansion = IsFolderNode(Node);
 }
 //---------------------------------------------------------------------------
-void __fastcall TLoginDialog::ExecuteTool(const UnicodeString & Name)
-{
-  UnicodeString Path;
-  if (!FindTool(Name, Path))
-  {
-    throw Exception(FMTLOAD(EXECUTE_APP_ERROR, (Name)));
-  }
-
-  ExecuteShellChecked(Path, L"");
-}
-//---------------------------------------------------------------------------
 void __fastcall TLoginDialog::RunPageantActionExecute(TObject * /*Sender*/)
 {
   ExecuteTool(PageantTool);

+ 0 - 1
source/forms/Login.h

@@ -358,7 +358,6 @@ private:
   TTreeNode * __fastcall GetNewSiteNode();
   void __fastcall SetNewSiteNodeLabel();
   inline TSessionData * __fastcall GetNodeSession(TTreeNode * Node);
-  void __fastcall ExecuteTool(const UnicodeString & Name);
   void __fastcall ReloadSessions(const UnicodeString & SelectSite);
   void __fastcall ResetSitesIncrementalSearch();
   bool __fastcall SitesIncrementalSearch(const UnicodeString & Text,

+ 19 - 0
source/forms/SiteAdvanced.cpp

@@ -104,6 +104,9 @@ void __fastcall TSiteAdvancedDialog::InitControls()
 
   SelectScaledImageList(ColorImageList);
   SetSessionColor((TColor)0);
+
+  UnicodeString Dummy;
+  PrivateKeyGenerateButton->Enabled = FindTool(PuttygenTool, Dummy);
 }
 //---------------------------------------------------------------------
 void __fastcall TSiteAdvancedDialog::LoadSession()
@@ -1069,6 +1072,7 @@ void __fastcall TSiteAdvancedDialog::ChangePage(TTabSheet * Tab)
 {
   PageControl->ActivePage = Tab;
   PageControlChange(PageControl);
+  FPrivateKeyMonitors.reset(NULL);
 }
 //---------------------------------------------------------------------------
 void __fastcall TSiteAdvancedDialog::PageControlChange(TObject *Sender)
@@ -1513,3 +1517,18 @@ void __fastcall TSiteAdvancedDialog::TlsCertificateFileEditAfterDialog(TObject *
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TSiteAdvancedDialog::PrivateKeyCreatedOrModified(TObject * /*Sender*/, const UnicodeString FileName)
+{
+  if (SameText(ExtractFileExt(FileName), FORMAT(L".%s", (PuttyKeyExt))))
+  {
+    PrivateKeyEdit3->FileName = FileName;
+  }
+}
+//---------------------------------------------------------------------------
+void __fastcall TSiteAdvancedDialog::PrivateKeyGenerateButtonClick(TObject * /*Sender*/)
+{
+  unsigned int Filters = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE;
+  FPrivateKeyMonitors.reset(StartCreationDirectoryMonitorsOnEachDrive(Filters, PrivateKeyCreatedOrModified));
+  ExecuteTool(PuttygenTool);
+}
+//---------------------------------------------------------------------------

+ 13 - 3
source/forms/SiteAdvanced.dfm

@@ -2004,13 +2004,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
           Left = 0
           Top = 154
           Width = 393
-          Height = 94
+          Height = 120
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Authentication parameters'
           TabOrder = 2
           DesignSize = (
             393
-            94)
+            120)
           object PrivateKeyLabel: TLabel
             Left = 12
             Top = 42
@@ -2048,10 +2048,20 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
             Text = 'PrivateKeyEdit3'
             OnChange = DataChange
           end
+          object PrivateKeyGenerateButton: TButton
+            Left = 12
+            Top = 86
+            Width = 101
+            Height = 25
+            Anchors = [akTop, akRight]
+            Caption = 'Ge&nerate...'
+            TabOrder = 2
+            OnClick = PrivateKeyGenerateButtonClick
+          end
         end
         object GSSAPIGroup: TGroupBox
           Left = 0
-          Top = 254
+          Top = 279
           Width = 393
           Height = 71
           Anchors = [akLeft, akTop, akRight]

+ 4 - 0
source/forms/SiteAdvanced.h

@@ -257,6 +257,7 @@ __published:
   TImageList *ColorImageList120;
   TImageList *ColorImageList144;
   TImageList *ColorImageList192;
+  TButton *PrivateKeyGenerateButton;
   void __fastcall DataChange(TObject *Sender);
   void __fastcall FormShow(TObject *Sender);
   void __fastcall PageControlChange(TObject *Sender);
@@ -289,6 +290,7 @@ __published:
   void __fastcall NoteMemoKeyDown(TObject *Sender, WORD &Key, TShiftState Shift);
   void __fastcall TlsCertificateFileEditAfterDialog(TObject *Sender, UnicodeString &Name,
           bool &Action);
+  void __fastcall PrivateKeyGenerateButtonClick(TObject *Sender);
 
 
 public:
@@ -312,6 +314,7 @@ private:
   TSessionData * FSessionData;
   TColor FColor;
   std::unique_ptr<TPopupMenu> FColorPopupMenu;
+  std::unique_ptr<TObjectList> FPrivateKeyMonitors;
 
   void __fastcall LoadSession();
   void __fastcall UpdateControls();
@@ -331,6 +334,7 @@ private:
   TTlsVersion __fastcall IndexToTlsVersion(int Index);
   int __fastcall TlsVersionToIndex(TTlsVersion TlsVersion);
   bool __fastcall IsNeon(TFSProtocol FSProtocol);
+  void __fastcall PrivateKeyCreatedOrModified(TObject * Sender, const UnicodeString FileName);
 };
 //----------------------------------------------------------------------------
 #endif

+ 40 - 0
source/windows/GUITools.cpp

@@ -224,6 +224,46 @@ bool __fastcall FindTool(const UnicodeString & Name, UnicodeString & Path)
   return Result;
 }
 //---------------------------------------------------------------------------
+void __fastcall ExecuteTool(const UnicodeString & Name)
+{
+  UnicodeString Path;
+  if (!FindTool(Name, Path))
+  {
+    throw Exception(FMTLOAD(EXECUTE_APP_ERROR, (Name)));
+  }
+
+  ExecuteShellChecked(Path, L"");
+}
+//---------------------------------------------------------------------------
+TObjectList * StartCreationDirectoryMonitorsOnEachDrive(unsigned int Filter, TFileChangedEvent OnChanged)
+{
+  std::unique_ptr<TObjectList> Result(new TObjectList());
+  for (char Drive = FirstDrive; Drive <= LastDrive; Drive++)
+  {
+    std::unique_ptr<TDirectoryMonitor> Monitor(new TDirectoryMonitor(Application));
+    TDriveInfoRec * DriveInfoRec = DriveInfo->Get(Drive);
+    if (DriveInfoRec->Valid &&
+        (DriveInfoRec->DriveType != DRIVE_CDROM))
+    {
+      try
+      {
+        Monitor->Path = DriveInfo->GetDriveRoot(Drive);
+        Monitor->WatchSubtree = true;
+        Monitor->WatchFilters = Filter;
+        Monitor->OnCreated = OnChanged;
+        Monitor->OnModified = OnChanged;
+        Monitor->Active = true;
+        Result->Add(Monitor.release());
+      }
+      catch (Exception & E)
+      {
+        // Ignore errors watching not-ready drives
+      }
+    }
+  }
+  return Result.release();
+}
+//---------------------------------------------------------------------------
 bool __fastcall CopyCommandToClipboard(const UnicodeString & Command)
 {
   bool Result = UseAlternativeFunction() && IsKeyPressed(VK_CONTROL);

+ 3 - 0
source/windows/GUITools.h

@@ -4,6 +4,7 @@
 //---------------------------------------------------------------------------
 #include <FileMasks.H>
 #include <Tbx.hpp>
+#include <DirectoryMonitor.hpp>
 //---------------------------------------------------------------------------
 class TSessionData;
 //---------------------------------------------------------------------------
@@ -11,12 +12,14 @@ typedef void __fastcall (__closure* TProcessMessagesEvent)();
 //---------------------------------------------------------------------------
 bool __fastcall FindFile(UnicodeString & Path);
 bool __fastcall FindTool(const UnicodeString & Name, UnicodeString & Path);
+void __fastcall ExecuteTool(const UnicodeString & Name);
 void __fastcall ExecuteShellChecked(const UnicodeString Path, const UnicodeString Params,
   bool ChangeWorkingDirectory = false);
 void __fastcall ExecuteShellChecked(const UnicodeString Command);
 bool __fastcall ExecuteShell(const UnicodeString Path, const UnicodeString Params,
   HANDLE & Handle);
 void __fastcall ExecuteShellCheckedAndWait(const UnicodeString Command, TProcessMessagesEvent ProcessMessages);
+TObjectList * StartCreationDirectoryMonitorsOnEachDrive(unsigned int Filter, TFileChangedEvent OnChanged);
 bool __fastcall CopyCommandToClipboard(const UnicodeString & Command);
 void __fastcall OpenSessionInPutty(const UnicodeString PuttyPath,
   TSessionData * SessionData);

+ 2 - 2
source/windows/Tools.cpp

@@ -1144,9 +1144,9 @@ static void __fastcall ConvertKey(UnicodeString & FileName, TKeyType Type)
 
   try
   {
-    FileName = ChangeFileExt(FileName, ".ppk");
+    FileName = ChangeFileExt(FileName, FORMAT(L".%s", (PuttyKeyExt)));
 
-    if (!SaveDialog(LoadStr(CONVERTKEY_SAVE_TITLE), LoadStr(CONVERTKEY_SAVE_FILTER), L"ppk", FileName))
+    if (!SaveDialog(LoadStr(CONVERTKEY_SAVE_TITLE), LoadStr(CONVERTKEY_SAVE_FILTER), PuttyKeyExt, FileName))
     {
       Abort();
     }