浏览代码

Bug 2029: Allow providing tunnel private key passphrase in scripting

https://winscp.net/tracker/2029
(cherry picked from commit ef4e6239c0bfe67436b581cff33f740144b5c0ea)

Source commit: 997e40368690dadc789786eab862e39f2e94661c
Martin Prikryl 4 年之前
父节点
当前提交
bb67c13b8c
共有 2 个文件被更改,包括 40 次插入1 次删除
  1. 36 1
      source/core/SessionData.cpp
  2. 4 0
      source/core/SessionData.h

+ 36 - 1
source/core/SessionData.cpp

@@ -292,6 +292,7 @@ void __fastcall TSessionData::DefaultSettings()
   TunnelUserName = L"";
   TunnelPassword = L"";
   TunnelPublicKeyFile = L"";
+  TunnelPassphrase = L"";
   TunnelLocalPortNumber = 0;
   TunnelPortFwd = L"";
   TunnelHostKey = L"";
@@ -467,6 +468,7 @@ void __fastcall TSessionData::NonPersistant()
   PROPERTY(TunnelUserName); \
   PROPERTY_HANDLER(TunnelPassword, F); \
   PROPERTY(TunnelPublicKeyFile); \
+  PROPERTY_HANDLER(TunnelPassphrase, F); \
   PROPERTY(TunnelLocalPortNumber); \
   PROPERTY(TunnelPortFwd); \
   PROPERTY(TunnelHostKey); \
@@ -855,6 +857,12 @@ void __fastcall TSessionData::DoLoad(THierarchicalStorage * Storage, bool PuttyI
     LOAD_PASSWORD(TunnelPassword, L"TunnelPasswordPlain");
   }
   TunnelPublicKeyFile = Storage->ReadString(L"TunnelPublicKeyFile", TunnelPublicKeyFile);
+  // Contrary to main session passphrase (which has -passphrase switch in scripting),
+  // we are loading tunnel passphrase, as there's no other way to provide it in scripting
+  if (!Configuration->DisablePasswordStoring)
+  {
+    LOAD_PASSWORD(TunnelPassphrase, L"TunnelPassphrasePlain");
+  }
   TunnelLocalPortNumber = Storage->ReadInteger(L"TunnelLocalPortNumber", TunnelLocalPortNumber);
   TunnelHostKey = Storage->ReadString(L"TunnelHostKey", TunnelHostKey);
 
@@ -982,6 +990,7 @@ void __fastcall TSessionData::Load(THierarchicalStorage * Storage, bool PuttyImp
         REWRITE_PASSWORD(Password, L"PasswordPlain");
         REWRITE_PASSWORD(TunnelPassword, L"TunnelPasswordPlain");
         REWRITE_PASSWORD(EncryptKey, L"EncryptKeyPlain");
+        REWRITE_PASSWORD(TunnelPassphrase, L"TunnelPassphrasePlain");
         #undef REWRITE_PASSWORD
         Storage->CloseSubKey();
       }
@@ -1780,6 +1789,7 @@ void __fastcall TSessionData::RecryptPasswords()
   NewPassword = NewPassword;
   ProxyPassword = ProxyPassword;
   TunnelPassword = TunnelPassword;
+  TunnelPassphrase = TunnelPassphrase;
   Passphrase = Passphrase;
   EncryptKey = EncryptKey;
 }
@@ -1806,7 +1816,8 @@ bool __fastcall TSessionData::HasAnyPassword()
     HasAnySessionPassword() ||
     !FProxyPassword.IsEmpty() ||
     !FEncryptKey.IsEmpty() ||
-    !FPassphrase.IsEmpty();
+    !FPassphrase.IsEmpty() ||
+    !FTunnelPassphrase.IsEmpty();
 }
 //---------------------------------------------------------------------
 void __fastcall TSessionData::ClearSessionPasswords()
@@ -1963,6 +1974,8 @@ bool __fastcall TSessionData::MaskPasswordInOptionParameter(const UnicodeString
           SameText(Key, L"ProxyPasswordEnc") ||
           SameText(Key, L"TunnelPassword") ||
           SameText(Key, L"TunnelPasswordPlain") ||
+          SameText(Key, L"TunnelPassphrase") ||
+          SameText(Key, L"TunnelPassphrasePlain") ||
           SameText(Key, L"EncryptKey"))
       {
         Param = Key + L"=" + PasswordMask;
@@ -1992,6 +2005,10 @@ void __fastcall TSessionData::MaskPasswords()
   {
     TunnelPassword = PasswordMask;
   }
+  if (!TunnelPassphrase.IsEmpty())
+  {
+    TunnelPassphrase = PasswordMask;
+  }
   if (!EncryptKey.IsEmpty())
   {
     EncryptKey = PasswordMask;
@@ -2489,6 +2506,7 @@ TSessionData * TSessionData::CreateTunnelData(int TunnelLocalPortNumber)
   TunnelData->UserName = TunnelUserName;
   TunnelData->Password = TunnelPassword;
   TunnelData->PublicKeyFile = TunnelPublicKeyFile;
+  TunnelData->Passphrase = TunnelPassphrase;
   UnicodeString AHostName = HostNameExpanded;
   if (IsIPv6Literal(AHostName))
   {
@@ -4195,13 +4213,30 @@ UnicodeString __fastcall TSessionData::GetTunnelPassword() const
   return DecryptPassword(FTunnelPassword, TunnelUserName+TunnelHostName);
 }
 //---------------------------------------------------------------------
+void __fastcall TSessionData::SetTunnelPassphrase(UnicodeString avalue)
+{
+  RawByteString value = EncryptPassword(avalue, TunnelPublicKeyFile);
+  SET_SESSION_PROPERTY(TunnelPassphrase);
+}
+//---------------------------------------------------------------------
+UnicodeString __fastcall TSessionData::GetTunnelPassphrase() const
+{
+  return DecryptPassword(FTunnelPassphrase, TunnelPublicKeyFile);
+}
+//---------------------------------------------------------------------
 void __fastcall TSessionData::SetTunnelPublicKeyFile(UnicodeString value)
 {
   if (FTunnelPublicKeyFile != value)
   {
+    // TunnelPublicKeyFile is key for TunnelPassphrase encryption
+    UnicodeString XTunnelPassphrase = TunnelPassphrase;
+
     // StripPathQuotes should not be needed as we do not feed quotes anymore
     FTunnelPublicKeyFile = StripPathQuotes(value);
     Modify();
+
+    TunnelPassphrase = XTunnelPassphrase;
+    Shred(XTunnelPassphrase);
   }
 }
 //---------------------------------------------------------------------

+ 4 - 0
source/core/SessionData.h

@@ -206,6 +206,7 @@ private:
   UnicodeString FTunnelUserName;
   RawByteString FTunnelPassword;
   UnicodeString FTunnelPublicKeyFile;
+  RawByteString FTunnelPassphrase;
   int FTunnelLocalPortNumber;
   UnicodeString FTunnelPortFwd;
   UnicodeString FTunnelHostKey;
@@ -389,6 +390,8 @@ private:
   void __fastcall SetTunnelPassword(UnicodeString value);
   UnicodeString __fastcall GetTunnelPassword() const;
   void __fastcall SetTunnelPublicKeyFile(UnicodeString value);
+  void __fastcall SetTunnelPassphrase(UnicodeString value);
+  UnicodeString __fastcall GetTunnelPassphrase() const;
   void __fastcall SetTunnelPortFwd(UnicodeString value);
   void __fastcall SetTunnelLocalPortNumber(int value);
   bool __fastcall GetTunnelAutoassignLocalPortNumber();
@@ -660,6 +663,7 @@ public:
   __property UnicodeString TunnelUserName = { read = FTunnelUserName, write = SetTunnelUserName };
   __property UnicodeString TunnelPassword = { read = GetTunnelPassword, write = SetTunnelPassword };
   __property UnicodeString TunnelPublicKeyFile = { read = FTunnelPublicKeyFile, write = SetTunnelPublicKeyFile };
+  __property UnicodeString TunnelPassphrase = { read = GetTunnelPassphrase, write = SetTunnelPassphrase };
   __property bool TunnelAutoassignLocalPortNumber = { read = GetTunnelAutoassignLocalPortNumber };
   __property int TunnelLocalPortNumber = { read = FTunnelLocalPortNumber, write = SetTunnelLocalPortNumber };
   __property UnicodeString TunnelPortFwd = { read = FTunnelPortFwd, write = SetTunnelPortFwd };