Browse Source

Bug 2006: Include host key of tunnel session in generated code

https://winscp.net/tracker/2006

Source commit: aed06dd9b320155cdacf7aa01780d5130996fffe
Martin Prikryl 4 years ago
parent
commit
e9471add4b
3 changed files with 72 additions and 46 deletions
  1. 61 0
      source/core/SessionData.cpp
  2. 1 0
      source/core/SessionData.h
  3. 10 46
      source/core/Terminal.cpp

+ 61 - 0
source/core/SessionData.cpp

@@ -1057,6 +1057,7 @@ void __fastcall TSessionData::DoSave(THierarchicalStorage * Storage,
   WRITE_DATA(Bool, AgentFwd);
   WRITE_DATA(Bool, AuthKI);
   WRITE_DATA(Bool, AuthKIPassword);
+  WRITE_DATA_EX(String, L"SshHostKey", HostKey, );
   WRITE_DATA(String, Note);
 
   WRITE_DATA(Bool, AuthGSSAPI);
@@ -1232,6 +1233,7 @@ void __fastcall TSessionData::DoSave(THierarchicalStorage * Storage,
     WRITE_DATA(String, TunnelUserName);
     WRITE_DATA(String, TunnelPublicKeyFile);
     WRITE_DATA(Integer, TunnelLocalPortNumber);
+    WRITE_DATA(String, TunnelHostKey);
 
     WRITE_DATA(Bool, FtpPasvMode);
     WRITE_DATA_EX(Integer, L"FtpForcePasvIp2", FtpForcePasvIp, );
@@ -2551,6 +2553,57 @@ void __fastcall TSessionData::RollbackTunnel()
   FLogicalHostName = L"";
 }
 //---------------------------------------------------------------------
+TSessionData * TSessionData::CreateTunnelData(int TunnelLocalPortNumber)
+{
+  std::unique_ptr<TSessionData> TunnelData(new TSessionData(EmptyStr));
+  TunnelData->Assign(StoredSessions->DefaultSettings);
+  TunnelData->Name = FMTLOAD(TUNNEL_SESSION_NAME, (SessionName));
+  TunnelData->Tunnel = false;
+  TunnelData->HostName = TunnelHostName;
+  TunnelData->PortNumber = TunnelPortNumber;
+  TunnelData->UserName = TunnelUserName;
+  TunnelData->Password = TunnelPassword;
+  TunnelData->PublicKeyFile = TunnelPublicKeyFile;
+  UnicodeString AHostName = HostNameExpanded;
+  if (IsIPv6Literal(AHostName))
+  {
+    AHostName = EscapeIPv6Literal(AHostName);
+  }
+  TunnelData->TunnelPortFwd = FORMAT(L"L%d\t%s:%d",
+    (TunnelLocalPortNumber, AHostName, PortNumber));
+  TunnelData->HostKey = TunnelHostKey;
+
+  // inherit proxy options on the main session
+  TunnelData->ProxyMethod = ProxyMethod;
+  TunnelData->ProxyHost = ProxyHost;
+  TunnelData->ProxyPort = ProxyPort;
+  TunnelData->ProxyUsername = ProxyUsername;
+  TunnelData->ProxyPassword = ProxyPassword;
+  TunnelData->ProxyTelnetCommand = ProxyTelnetCommand;
+  TunnelData->ProxyLocalCommand = ProxyLocalCommand;
+  TunnelData->ProxyDNS = ProxyDNS;
+  TunnelData->ProxyLocalhost = ProxyLocalhost;
+
+  // inherit most SSH options of the main session (except for private key and bugs)
+  TunnelData->Compression = Compression;
+  TunnelData->CipherList = CipherList;
+  TunnelData->Ssh2DES = Ssh2DES;
+
+  TunnelData->KexList = KexList;
+  TunnelData->RekeyData = RekeyData;
+  TunnelData->RekeyTime = RekeyTime;
+
+  TunnelData->SshNoUserAuth = SshNoUserAuth;
+  TunnelData->AuthGSSAPI = AuthGSSAPI;
+  TunnelData->AuthGSSAPIKEX = AuthGSSAPIKEX;
+  TunnelData->GSSAPIFwdTGT = GSSAPIFwdTGT;
+  TunnelData->TryAgent = TryAgent;
+  TunnelData->AgentFwd = AgentFwd;
+  TunnelData->AuthKI = AuthKI;
+  TunnelData->AuthKIPassword = AuthKIPassword;
+  return TunnelData.release();
+}
+//---------------------------------------------------------------------
 void __fastcall TSessionData::ExpandEnvironmentVariables()
 {
   HostName = HostNameExpanded;
@@ -3577,6 +3630,14 @@ void __fastcall TSessionData::LookupLastFingerprint()
   {
     HostKey = Configuration->LastFingerprint(SiteKey, FingerprintType);
   }
+
+  if (Tunnel)
+  {
+    // not used anyway
+    int TunnelPortNumber = std::max(TunnelLocalPortNumber, Configuration->TunnelLocalPortNumberLow);
+    std::unique_ptr<TSessionData> TunnelData(CreateTunnelData(TunnelPortNumber));
+    TunnelHostKey = Configuration->LastFingerprint(TunnelData->SiteKey, SshFingerprintType);
+  }
 }
 //---------------------------------------------------------------------
 UnicodeString __fastcall TSessionData::GenerateOpenCommandArgs(bool Rtf)

+ 1 - 0
source/core/SessionData.h

@@ -511,6 +511,7 @@ public:
   TStrings * __fastcall SaveToOptions(const TSessionData * Default, bool SaveName, bool PuttyExport);
   void __fastcall ConfigureTunnel(int PortNumber);
   void __fastcall RollbackTunnel();
+  TSessionData * CreateTunnelData(int TunnelLocalPortNumber);
   void __fastcall ExpandEnvironmentVariables();
   void __fastcall DisableAuthentationsExceptPassword();
   bool __fastcall IsSame(const TSessionData * Default, bool AdvancedOnly);

+ 10 - 46
source/core/Terminal.cpp

@@ -1504,52 +1504,7 @@ void __fastcall TTerminal::OpenTunnel()
 
   try
   {
-    FTunnelData = new TSessionData(L"");
-    FTunnelData->Assign(StoredSessions->DefaultSettings);
-    FTunnelData->Name = FMTLOAD(TUNNEL_SESSION_NAME, (FSessionData->SessionName));
-    FTunnelData->Tunnel = false;
-    FTunnelData->HostName = FSessionData->TunnelHostName;
-    FTunnelData->PortNumber = FSessionData->TunnelPortNumber;
-    FTunnelData->UserName = FSessionData->TunnelUserName;
-    FTunnelData->Password = FSessionData->TunnelPassword;
-    FTunnelData->PublicKeyFile = FSessionData->TunnelPublicKeyFile;
-    UnicodeString HostName = FSessionData->HostNameExpanded;
-    if (IsIPv6Literal(HostName))
-    {
-      HostName = EscapeIPv6Literal(HostName);
-    }
-    FTunnelData->TunnelPortFwd = FORMAT(L"L%d\t%s:%d",
-      (FTunnelLocalPortNumber, HostName, FSessionData->PortNumber));
-    FTunnelData->HostKey = FSessionData->TunnelHostKey;
-
-    // inherit proxy options on the main session
-    FTunnelData->ProxyMethod = FSessionData->ProxyMethod;
-    FTunnelData->ProxyHost = FSessionData->ProxyHost;
-    FTunnelData->ProxyPort = FSessionData->ProxyPort;
-    FTunnelData->ProxyUsername = FSessionData->ProxyUsername;
-    FTunnelData->ProxyPassword = FSessionData->ProxyPassword;
-    FTunnelData->ProxyTelnetCommand = FSessionData->ProxyTelnetCommand;
-    FTunnelData->ProxyLocalCommand = FSessionData->ProxyLocalCommand;
-    FTunnelData->ProxyDNS = FSessionData->ProxyDNS;
-    FTunnelData->ProxyLocalhost = FSessionData->ProxyLocalhost;
-
-    // inherit most SSH options of the main session (except for private key and bugs)
-    FTunnelData->Compression = FSessionData->Compression;
-    FTunnelData->CipherList = FSessionData->CipherList;
-    FTunnelData->Ssh2DES = FSessionData->Ssh2DES;
-
-    FTunnelData->KexList = FSessionData->KexList;
-    FTunnelData->RekeyData = FSessionData->RekeyData;
-    FTunnelData->RekeyTime = FSessionData->RekeyTime;
-
-    FTunnelData->SshNoUserAuth = FSessionData->SshNoUserAuth;
-    FTunnelData->AuthGSSAPI = FSessionData->AuthGSSAPI;
-    FTunnelData->AuthGSSAPIKEX = FSessionData->AuthGSSAPIKEX;
-    FTunnelData->GSSAPIFwdTGT = FSessionData->GSSAPIFwdTGT;
-    FTunnelData->TryAgent = FSessionData->TryAgent;
-    FTunnelData->AgentFwd = FSessionData->AgentFwd;
-    FTunnelData->AuthKI = FSessionData->AuthKI;
-    FTunnelData->AuthKIPassword = FSessionData->AuthKIPassword;
+    FTunnelData = FSessionData->CreateTunnelData(FTunnelLocalPortNumber);
 
     // The Started argument is not used with Parent being set
     FTunnelLog = new TSessionLog(this, TDateTime(), FTunnelData, Configuration);
@@ -4972,6 +4927,15 @@ void __fastcall TTerminal::FillSessionDataForCode(TSessionData * Data)
   {
     Data->HostKey = SessionInfo.CertificateFingerprintSHA256;
   }
+
+  if (FTunnel != NULL)
+  {
+    const TSessionInfo & TunnelSessionInfo = FTunnel->GetSessionInfo();
+    if (DebugAlwaysTrue(!TunnelSessionInfo.HostKeyFingerprintSHA256.IsEmpty()))
+    {
+      Data->TunnelHostKey = TunnelSessionInfo.HostKeyFingerprintSHA256;
+    }
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TTerminal::UpdateSessionCredentials(TSessionData * Data)