Explorar o código

Removing support for SSH-1

(cherry picked from commit 5dfcf1eb9f16119f6dbc13a0ea4a3f69f0433ae2)

Source commit: 1fd4286a576bf4525c8dd00849cdcf958cbf5eb8
Martin Prikryl %!s(int64=4) %!d(string=hai) anos
pai
achega
cda4ea8a81

+ 0 - 23
source/Putty.cbproj

@@ -170,21 +170,6 @@
 			<BuildOrder>23</BuildOrder>
 			<BuildOrder>19</BuildOrder>
 		</CppCompile>
-		<CppCompile Include="putty\ssh1bpp.c">
-			<BuildOrder>53</BuildOrder>
-		</CppCompile>
-		<CppCompile Include="putty\ssh1censor.c">
-			<BuildOrder>57</BuildOrder>
-		</CppCompile>
-		<CppCompile Include="putty\ssh1connection.c">
-			<BuildOrder>64</BuildOrder>
-		</CppCompile>
-		<CppCompile Include="putty\ssh1connection-client.c">
-			<BuildOrder>71</BuildOrder>
-		</CppCompile>
-		<CppCompile Include="putty\ssh1login.c">
-			<BuildOrder>65</BuildOrder>
-		</CppCompile>
 		<CppCompile Include="putty\ssh2bpp.c">
 			<BuildOrder>54</BuildOrder>
 		</CppCompile>
@@ -245,14 +230,6 @@
 		<CppCompile Include="putty\sshcommon.c">
 			<BuildOrder>62</BuildOrder>
 		</CppCompile>
-		<CppCompile Include="putty\sshcrc.c">
-			<BuildOrder>38</BuildOrder>
-			<BuildOrder>36</BuildOrder>
-		</CppCompile>
-		<CppCompile Include="putty\sshcrcda.c">
-			<BuildOrder>41</BuildOrder>
-			<BuildOrder>35</BuildOrder>
-		</CppCompile>
 		<CppCompile Include="putty\sshdes.c">
 			<BuildOrder>44</BuildOrder>
 			<BuildOrder>32</BuildOrder>

+ 0 - 5
source/core/PuttyIntf.cpp

@@ -957,11 +957,6 @@ UnicodeString __fastcall ParseOpenSshPubLine(const UnicodeString & Line, const s
   return Result;
 }
 //---------------------------------------------------------------------------
-UnicodeString __fastcall GetSsh1KeyType()
-{
-  return UnicodeString(ssh_rsa.cache_id);
-}
-//---------------------------------------------------------------------------
 UnicodeString __fastcall GetKeyTypeHuman(const UnicodeString & KeyType)
 {
   UnicodeString Result;

+ 0 - 1
source/core/PuttyTools.h

@@ -37,7 +37,6 @@ void __fastcall DllHijackingProtection();
 UnicodeString __fastcall ParseOpenSshPubLine(const UnicodeString & Line, const struct ssh_keyalg *& Algorithm);
 //---------------------------------------------------------------------------
 UnicodeString __fastcall GetKeyTypeHuman(const UnicodeString & KeyType);
-UnicodeString __fastcall GetSsh1KeyType();
 //---------------------------------------------------------------------------
 bool IsOpenSSH(const UnicodeString & SshImplementation);
 //---------------------------------------------------------------------------

+ 17 - 60
source/core/SecureShell.cpp

@@ -123,27 +123,16 @@ inline void __fastcall TSecureShell::UpdateSessionInfo()
 {
   if (!FSessionInfoValid)
   {
-    FSshVersion = get_ssh_version(FBackendHandle);
+    DebugAssert(get_ssh_version(FBackendHandle) == 2);
     FSessionInfo.ProtocolBaseName = L"SSH";
     FSessionInfo.ProtocolName =
       FORMAT(L"%s-%d", (FSessionInfo.ProtocolBaseName, get_ssh_version(FBackendHandle)));
     FSessionInfo.SecurityProtocolName = FSessionInfo.ProtocolName;
 
-    if (FSshVersion == 1)
-    {
-      FSessionInfo.CSCipher = GetCipherName(get_cipher(FBackendHandle));
-      FSessionInfo.SCCipher = FSessionInfo.CSCipher;
-      // Retrieval of compression is not implemented for SSH-1
-      FSessionInfo.CSCompression = UnicodeString();
-      FSessionInfo.SCCompression = UnicodeString();
-    }
-    else
-    {
-      FSessionInfo.CSCipher = GetCipherName(get_cscipher(FBackendHandle));
-      FSessionInfo.SCCipher = GetCipherName(get_sccipher(FBackendHandle));
-      FSessionInfo.CSCompression = GetCompressorName(get_cscomp(FBackendHandle));
-      FSessionInfo.SCCompression = GetDecompressorName(get_sccomp(FBackendHandle));
-    }
+    FSessionInfo.CSCipher = GetCipherName(get_cscipher(FBackendHandle));
+    FSessionInfo.SCCipher = GetCipherName(get_sccipher(FBackendHandle));
+    FSessionInfo.CSCompression = GetCompressorName(get_cscomp(FBackendHandle));
+    FSessionInfo.SCCompression = GetDecompressorName(get_sccomp(FBackendHandle));
 
     FSessionInfoValid = true;
   }
@@ -259,10 +248,8 @@ Conf * __fastcall TSecureShell::StoreToConfig(TSessionData * Data, bool Simple)
   conf_set_filename(conf, CONF_keyfile, KeyFileFileName);
   filename_free(KeyFileFileName);
 
-  conf_set_int(conf, CONF_sshprot, Data->SshProt);
   conf_set_bool(conf, CONF_ssh2_des_cbc, Data->Ssh2DES);
   conf_set_bool(conf, CONF_ssh_no_userauth, Data->SshNoUserAuth);
-  conf_set_bool(conf, CONF_try_tis_auth, Data->AuthTIS);
   conf_set_bool(conf, CONF_try_ki_auth, Data->AuthKI);
   conf_set_bool(conf, CONF_try_gssapi_auth, Data->AuthGSSAPI);
   conf_set_bool(conf, CONF_try_gssapi_kex, Data->AuthGSSAPIKEX);
@@ -285,9 +272,6 @@ Conf * __fastcall TSecureShell::StoreToConfig(TSessionData * Data, bool Simple)
   conf_set_int(conf, CONF_proxy_dns, Data->ProxyDNS);
   conf_set_bool(conf, CONF_even_proxy_localhost, Data->ProxyLocalhost);
 
-  conf_set_int(conf, CONF_sshbug_ignore1, Data->Bug[sbIgnore1]);
-  conf_set_int(conf, CONF_sshbug_plainpw1, Data->Bug[sbPlainPW1]);
-  conf_set_int(conf, CONF_sshbug_rsa1, Data->Bug[sbRSA1]);
   conf_set_int(conf, CONF_sshbug_hmac2, Data->Bug[sbHMAC2]);
   conf_set_int(conf, CONF_sshbug_derivekey2, Data->Bug[sbDeriveKey2]);
   conf_set_int(conf, CONF_sshbug_rsapad2, Data->Bug[sbRSAPad2]);
@@ -2176,14 +2160,7 @@ unsigned long __fastcall TSecureShell::MaxPacketSize()
     UpdateSessionInfo();
   }
 
-  if (FSshVersion == 1)
-  {
-    return 0;
-  }
-  else
-  {
-    return winscp_query(FBackendHandle, WINSCP_QUERY_REMMAXPKT);
-  }
+  return winscp_query(FBackendHandle, WINSCP_QUERY_REMMAXPKT);
 }
 //---------------------------------------------------------------------------
 UnicodeString __fastcall TSecureShell::FormatKeyStr(UnicodeString KeyStr)
@@ -2416,16 +2393,8 @@ UnicodeString TSecureShell::StoreHostKey(
 void TSecureShell::ParseFingerprint(const UnicodeString & Fingerprint, UnicodeString & SignKeyType, UnicodeString & Hash)
 {
   UnicodeString Buf = Fingerprint;
-  UnicodeString SignKeyAlg, SignKeySize;
-  if (get_ssh_version(FBackendHandle) == 1)
-  {
-    SignKeyAlg = GetSsh1KeyType();
-  }
-  else
-  {
-    SignKeyAlg = CutToChar(Buf, L' ', false);
-  }
-  SignKeySize = CutToChar(Buf, L' ', false);
+  UnicodeString SignKeyAlg = CutToChar(Buf, L' ', false);
+  UnicodeString SignKeySize = CutToChar(Buf, L' ', false);
   SignKeyType = SignKeyAlg + L' ' + SignKeySize;
   Hash = Buf;
 }
@@ -2448,21 +2417,16 @@ void __fastcall TSecureShell::VerifyHostKey(
 
   UnicodeString SignKeyType, MD5, SHA256;
   ParseFingerprint(AFingerprintMD5, SignKeyType, MD5);
-  if (get_ssh_version(FBackendHandle) == 1)
+
+  DebugAssert(get_ssh_version(FBackendHandle) == 2);
+  UnicodeString SignKeyTypeSHA256;
+  ParseFingerprint(AFingerprintSHA256, SignKeyTypeSHA256, SHA256);
+  DebugAssert(SignKeyTypeSHA256 == SignKeyType);
+  if (DebugAlwaysTrue(StartsText(L"SHA256:", SHA256)))
   {
-    DebugAssert(AFingerprintSHA256.IsEmpty());
-    SHA256 = L"-";
-  }
-  else
-  {
-    UnicodeString SignKeyTypeSHA256;
-    ParseFingerprint(AFingerprintSHA256, SignKeyTypeSHA256, SHA256);
-    DebugAssert(SignKeyTypeSHA256 == SignKeyType);
-    if (DebugAlwaysTrue(StartsText(L"SHA256:", SHA256)))
-    {
-      CutToChar(SHA256, L':', false);
-    }
+    CutToChar(SHA256, L':', false);
   }
+
   UnicodeString FingerprintMD5 = SignKeyType + L' ' + MD5;
   DebugAssert(AFingerprintMD5 == FingerprintMD5);
   UnicodeString FingerprintSHA256 = SignKeyType + L' ' + SHA256;
@@ -2755,14 +2719,7 @@ void __fastcall TSecureShell::CollectUsage()
     Configuration->Usage->Inc(L"OpenedSessionsPrivateKey2");
   }
 
-  if (FSshVersion == 1)
-  {
-    Configuration->Usage->Inc(L"OpenedSessionsSSH1");
-  }
-  else if (FSshVersion == 2)
-  {
-    Configuration->Usage->Inc(L"OpenedSessionsSSH2");
-  }
+  Configuration->Usage->Inc(L"OpenedSessionsSSH2");
 
   if (SshImplementation == sshiOpenSSH)
   {

+ 0 - 1
source/core/SecureShell.h

@@ -45,7 +45,6 @@ private:
   bool FStoredPasswordTried;
   bool FStoredPasswordTriedForKI;
   bool FStoredPassphraseTried;
-  int FSshVersion;
   bool FOpened;
   bool FClosed;
   int FWaiting;

+ 0 - 41
source/core/SessionData.cpp

@@ -34,7 +34,6 @@ const UnicodeString CipherNames[CIPHER_COUNT] = {L"WARN", L"3des", L"blowfish",
 const UnicodeString KexNames[KEX_COUNT] = {L"WARN", L"dh-group1-sha1", L"dh-group14-sha1", L"dh-gex-sha1", L"rsa", L"ecdh"};
 const UnicodeString HostKeyNames[HOSTKEY_COUNT] = {L"WARN", L"rsa", L"dsa", L"ecdsa", L"ed25519", L"ed448"};
 const UnicodeString GssLibNames[GSSLIB_COUNT] = {L"gssapi32", L"sspi", L"custom"};
-const wchar_t SshProtList[][10] = {L"1", L"1>2", L"2>1", L"2"};
 // Update also order in Ssh2CipherList()
 const TCipher DefaultCipherList[CIPHER_COUNT] =
   { cipAES, cipChaCha20, cipBlowfish, cip3DES, cipWarn, cipArcfour, cipDES };
@@ -129,7 +128,6 @@ void __fastcall TSessionData::DefaultSettings()
   Timeout = 15;
   TryAgent = true;
   AgentFwd = false;
-  AuthTIS = false;
   AuthKI = true;
   AuthKIPassword = true;
   AuthGSSAPI = true;
@@ -138,7 +136,6 @@ void __fastcall TSessionData::DefaultSettings()
   LogicalHostName = L"";
   ChangeUsername = false;
   Compression = false;
-  SshProt = ssh2only;
   Ssh2DES = false;
   SshNoUserAuth = false;
   for (int Index = 0; Index < CIPHER_COUNT; Index++)
@@ -337,11 +334,9 @@ void __fastcall TSessionData::NonPersistant()
   PROPERTY(Timeout); \
   PROPERTY(TryAgent); \
   PROPERTY(AgentFwd); \
-  PROPERTY(AuthTIS); \
   PROPERTY(LogicalHostName); \
   PROPERTY(ChangeUsername); \
   PROPERTY(Compression); \
-  PROPERTY(SshProt); \
   PROPERTY(Ssh2DES); \
   PROPERTY(SshNoUserAuth); \
   PROPERTY(CipherList); \
@@ -659,7 +654,6 @@ void __fastcall TSessionData::DoLoad(THierarchicalStorage * Storage, bool PuttyI
   Timeout = Storage->ReadInteger(L"Timeout", Timeout);
   TryAgent = Storage->ReadBool(L"TryAgent", TryAgent);
   AgentFwd = Storage->ReadBool(L"AgentFwd", AgentFwd);
-  AuthTIS = Storage->ReadBool(L"AuthTIS", AuthTIS);
   AuthKI = Storage->ReadBool(L"AuthKI", AuthKI);
   AuthKIPassword = Storage->ReadBool(L"AuthKIPassword", AuthKIPassword);
   // Continue to use setting keys of previous kerberos implementation (vaclav tomec),
@@ -674,17 +668,6 @@ void __fastcall TSessionData::DoLoad(THierarchicalStorage * Storage, bool PuttyI
   LogicalHostName = Storage->ReadString(L"LogicalHostName", Storage->ReadString(L"GSSAPIServerRealm", Storage->ReadString(L"KerbPrincipal", LogicalHostName)));
   ChangeUsername = Storage->ReadBool(L"ChangeUsername", ChangeUsername);
   Compression = Storage->ReadBool(L"Compression", Compression);
-  TSshProt ASshProt = (TSshProt)Storage->ReadInteger(L"SshProt", SshProt);
-  // Old sessions may contain the values correponding to the fallbacks we used to allow; migrate them
-  if (ASshProt == ssh2deprecated)
-  {
-    ASshProt = ssh2only;
-  }
-  else if (ASshProt == ssh1deprecated)
-  {
-    ASshProt = ssh1only;
-  }
-  SshProt = ASshProt;
   Ssh2DES = Storage->ReadBool(L"Ssh2DES", Ssh2DES);
   SshNoUserAuth = Storage->ReadBool(L"SshNoUserAuth", SshNoUserAuth);
   CipherList = Storage->ReadString(L"Cipher", CipherList);
@@ -796,9 +779,6 @@ void __fastcall TSessionData::DoLoad(THierarchicalStorage * Storage, bool PuttyI
   #define READ_BUG(BUG) \
     Bug[sb##BUG] = TAutoSwitch(2 - Storage->ReadInteger(L"Bug"#BUG, \
       2 - Bug[sb##BUG]));
-  READ_BUG(Ignore1);
-  READ_BUG(PlainPW1);
-  READ_BUG(RSA1);
   READ_BUG(HMAC2);
   READ_BUG(DeriveKey2);
   READ_BUG(RSAPad2);
@@ -1038,7 +1018,6 @@ void __fastcall TSessionData::DoSave(THierarchicalStorage * Storage,
   WRITE_DATA(Integer, Timeout);
   WRITE_DATA(Bool, TryAgent);
   WRITE_DATA(Bool, AgentFwd);
-  WRITE_DATA(Bool, AuthTIS);
   WRITE_DATA(Bool, AuthKI);
   WRITE_DATA(Bool, AuthKIPassword);
   WRITE_DATA(String, Note);
@@ -1063,7 +1042,6 @@ void __fastcall TSessionData::DoSave(THierarchicalStorage * Storage,
 
   WRITE_DATA(Bool, ChangeUsername);
   WRITE_DATA(Bool, Compression);
-  WRITE_DATA(Integer, SshProt);
   WRITE_DATA(Bool, Ssh2DES);
   WRITE_DATA(Bool, SshNoUserAuth);
   WRITE_DATA_EX(String, L"Cipher", CipherList, );
@@ -1170,9 +1148,6 @@ void __fastcall TSessionData::DoSave(THierarchicalStorage * Storage,
 
   #define WRITE_DATA_CONV_FUNC(X) (2 - (X))
   #define WRITE_BUG(BUG) WRITE_DATA_CONV(Integer, L"Bug" #BUG, Bug[sb##BUG]);
-  WRITE_BUG(Ignore1);
-  WRITE_BUG(PlainPW1);
-  WRITE_BUG(RSA1);
   WRITE_BUG(HMAC2);
   WRITE_BUG(DeriveKey2);
   WRITE_BUG(RSAPad2);
@@ -2641,11 +2616,6 @@ void __fastcall TSessionData::SetAgentFwd(bool value)
   SET_SESSION_PROPERTY(AgentFwd);
 }
 //---------------------------------------------------------------------
-void __fastcall TSessionData::SetAuthTIS(bool value)
-{
-  SET_SESSION_PROPERTY(AuthTIS);
-}
-//---------------------------------------------------------------------
 void __fastcall TSessionData::SetAuthKI(bool value)
 {
   SET_SESSION_PROPERTY(AuthKI);
@@ -2681,11 +2651,6 @@ void __fastcall TSessionData::SetCompression(bool value)
   SET_SESSION_PROPERTY(Compression);
 }
 //---------------------------------------------------------------------
-void __fastcall TSessionData::SetSshProt(TSshProt value)
-{
-  SET_SESSION_PROPERTY(SshProt);
-}
-//---------------------------------------------------------------------
 void __fastcall TSessionData::SetSsh2DES(bool value)
 {
   SET_SESSION_PROPERTY(Ssh2DES);
@@ -2696,11 +2661,6 @@ void __fastcall TSessionData::SetSshNoUserAuth(bool value)
   SET_SESSION_PROPERTY(SshNoUserAuth);
 }
 //---------------------------------------------------------------------
-UnicodeString __fastcall TSessionData::GetSshProtStr()
-{
-  return SshProtList[FSshProt];
-}
-//---------------------------------------------------------------------
 bool __fastcall TSessionData::GetUsesSsh()
 {
   return IsSshProtocol(FSProtocol);
@@ -4327,7 +4287,6 @@ UnicodeString __fastcall TSessionData::ComposePath(
 void __fastcall TSessionData::DisableAuthentationsExceptPassword()
 {
   SshNoUserAuth = false;
-  AuthTIS = false;
   AuthKI = false;
   AuthKIPassword = false;
   AuthGSSAPI = false;

+ 1 - 10
source/core/SessionData.h

@@ -17,7 +17,6 @@ enum TFSProtocol { fsSCPonly = 0, fsSFTP = 1, fsSFTPonly = 2, fsFTP = 5, fsWebDA
 #define FSPROTOCOL_COUNT (fsS3+1)
 extern const wchar_t * ProxyMethodNames;
 enum TProxyMethod { pmNone, pmSocks4, pmSocks5, pmHTTP, pmTelnet, pmCmd };
-enum TSshProt { ssh1only, ssh1deprecated, ssh2deprecated, ssh2only };
 enum TKex { kexWarn, kexDHGroup1, kexDHGroup14, kexDHGEx, kexRSA, kexECDH };
 #define KEX_COUNT (kexECDH+1)
 enum THostKey { hkWarn, hkRSA, hkDSA, hkECDSA, hkED25519, hkED448, hkMax };
@@ -25,7 +24,7 @@ enum THostKey { hkWarn, hkRSA, hkDSA, hkECDSA, hkED25519, hkED448, hkMax };
 enum TGssLib { gssGssApi32, gssSspi, gssCustom };
 #define GSSLIB_COUNT (gssCustom+1)
 // names have to match PuTTY registry entries (see settings.c)
-enum TSshBug { sbIgnore1, sbPlainPW1, sbRSA1, sbHMAC2, sbDeriveKey2, sbRSAPad2,
+enum TSshBug { sbHMAC2, sbDeriveKey2, sbRSAPad2,
   sbPKSessID2, sbRekey2, sbMaxPkt2, sbIgnore2, sbOldGex2, sbWinAdj, sbChanReq };
 #define BUG_COUNT (sbChanReq+1)
 enum TSftpBug { sbSymlink, sbSignedTS };
@@ -114,7 +113,6 @@ private:
   bool FTryAgent;
   bool FAgentFwd;
   UnicodeString FListingCommand;
-  bool FAuthTIS;
   bool FAuthKI;
   bool FAuthKIPassword;
   bool FAuthGSSAPI;
@@ -122,7 +120,6 @@ private:
   bool FGSSAPIFwdTGT;
   bool FChangeUsername;
   bool FCompression;
-  TSshProt FSshProt;
   bool FSsh2DES;
   bool FSshNoUserAuth;
   TCipher FCiphers[CIPHER_COUNT];
@@ -263,7 +260,6 @@ private:
   void __fastcall SetPingInterval(int value);
   void __fastcall SetTryAgent(bool value);
   void __fastcall SetAgentFwd(bool value);
-  void __fastcall SetAuthTIS(bool value);
   void __fastcall SetAuthKI(bool value);
   void __fastcall SetAuthKIPassword(bool value);
   void __fastcall SetAuthGSSAPI(bool value);
@@ -271,7 +267,6 @@ private:
   void __fastcall SetGSSAPIFwdTGT(bool value);
   void __fastcall SetChangeUsername(bool value);
   void __fastcall SetCompression(bool value);
-  void __fastcall SetSshProt(TSshProt value);
   void __fastcall SetSsh2DES(bool value);
   void __fastcall SetSshNoUserAuth(bool value);
   void __fastcall SetCipher(int Index, TCipher value);
@@ -334,7 +329,6 @@ private:
   void __fastcall SetSourceAddress(const UnicodeString & value);
   void __fastcall SetProtocolFeatures(const UnicodeString & value);
   void __fastcall SetSshSimple(bool value);
-  UnicodeString __fastcall GetSshProtStr();
   bool __fastcall GetUsesSsh();
   void __fastcall SetCipherList(UnicodeString value);
   UnicodeString __fastcall GetCipherList() const;
@@ -555,7 +549,6 @@ public:
   __property bool TryAgent  = { read=FTryAgent, write=SetTryAgent };
   __property bool AgentFwd  = { read=FAgentFwd, write=SetAgentFwd };
   __property UnicodeString ListingCommand = { read = FListingCommand, write = SetListingCommand };
-  __property bool AuthTIS  = { read=FAuthTIS, write=SetAuthTIS };
   __property bool AuthKI  = { read=FAuthKI, write=SetAuthKI };
   __property bool AuthKIPassword  = { read=FAuthKIPassword, write=SetAuthKIPassword };
   __property bool AuthGSSAPI  = { read=FAuthGSSAPI, write=SetAuthGSSAPI };
@@ -563,7 +556,6 @@ public:
   __property bool GSSAPIFwdTGT = { read=FGSSAPIFwdTGT, write=SetGSSAPIFwdTGT };
   __property bool ChangeUsername  = { read=FChangeUsername, write=SetChangeUsername };
   __property bool Compression  = { read=FCompression, write=SetCompression };
-  __property TSshProt SshProt  = { read=FSshProt, write=SetSshProt };
   __property bool UsesSsh = { read = GetUsesSsh };
   __property bool Ssh2DES  = { read=FSsh2DES, write=SetSsh2DES };
   __property bool SshNoUserAuth  = { read=FSshNoUserAuth, write=SetSshNoUserAuth };
@@ -618,7 +610,6 @@ public:
   __property UnicodeString SourceAddress = { read=FSourceAddress, write=SetSourceAddress };
   __property UnicodeString ProtocolFeatures = { read=FProtocolFeatures, write=SetProtocolFeatures };
   __property bool SshSimple  = { read=FSshSimple, write=SetSshSimple };
-  __property UnicodeString SshProtStr  = { read=GetSshProtStr };
   __property UnicodeString CipherList  = { read=GetCipherList, write=SetCipherList };
   __property UnicodeString KexList  = { read=GetKexList, write=SetKexList };
   __property UnicodeString HostKeyList  = { read=GetHostKeyList, write=SetHostKeyList };

+ 3 - 4
source/core/SessionInfo.cpp

@@ -1272,12 +1272,11 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
     }
     if (Data->UsesSsh)
     {
-      ADF(L"SSH protocol version: %s; Compression: %s",
-        (Data->SshProtStr, BooleanToEngStr(Data->Compression)));
+      ADF(L"Compression: %s", (BooleanToEngStr(Data->Compression)));
       ADF(L"Bypass authentication: %s",
        (BooleanToEngStr(Data->SshNoUserAuth)));
-      ADF(L"Try agent: %s; Agent forwarding: %s; TIS/CryptoCard: %s; KI: %s; GSSAPI: %s",
-        (BooleanToEngStr(Data->TryAgent), BooleanToEngStr(Data->AgentFwd), BooleanToEngStr(Data->AuthTIS),
+      ADF(L"Try agent: %s; Agent forwarding: %s; KI: %s; GSSAPI: %s",
+        (BooleanToEngStr(Data->TryAgent), BooleanToEngStr(Data->AgentFwd),
          BooleanToEngStr(Data->AuthKI), BooleanToEngStr(Data->AuthGSSAPI)));
       if (Data->AuthGSSAPI)
       {

+ 0 - 2
source/core/Terminal.cpp

@@ -1535,7 +1535,6 @@ void __fastcall TTerminal::OpenTunnel()
 
     // inherit most SSH options of the main session (except for private key and bugs)
     FTunnelData->Compression = FSessionData->Compression;
-    FTunnelData->SshProt = FSessionData->SshProt;
     FTunnelData->CipherList = FSessionData->CipherList;
     FTunnelData->Ssh2DES = FSessionData->Ssh2DES;
 
@@ -1549,7 +1548,6 @@ void __fastcall TTerminal::OpenTunnel()
     FTunnelData->GSSAPIFwdTGT = FSessionData->GSSAPIFwdTGT;
     FTunnelData->TryAgent = FSessionData->TryAgent;
     FTunnelData->AgentFwd = FSessionData->AgentFwd;
-    FTunnelData->AuthTIS = FSessionData->AuthTIS;
     FTunnelData->AuthKI = FSessionData->AuthKI;
     FTunnelData->AuthKIPassword = FSessionData->AuthKIPassword;
 

+ 8 - 64
source/forms/SiteAdvanced.cpp

@@ -63,9 +63,6 @@ void __fastcall TSiteAdvancedDialog::InitControls()
 {
   ComboAutoSwitchInitialize(UtfCombo);
 
-  ComboAutoSwitchInitialize(BugIgnore1Combo);
-  ComboAutoSwitchInitialize(BugPlainPW1Combo);
-  ComboAutoSwitchInitialize(BugRSA1Combo);
   ComboAutoSwitchInitialize(BugHMAC2Combo);
   ComboAutoSwitchInitialize(BugDeriveKey2Combo);
   ComboAutoSwitchInitialize(BugRSAPad2Combo);
@@ -243,7 +240,6 @@ void __fastcall TSiteAdvancedDialog::LoadSession()
     // Authentication page
     SshNoUserAuthCheck->Checked = FSessionData->SshNoUserAuth;
     TryAgentCheck->Checked = FSessionData->TryAgent;
-    AuthTISCheck->Checked = FSessionData->AuthTIS;
     AuthKICheck->Checked = FSessionData->AuthKI;
     AuthKIPasswordCheck->Checked = FSessionData->AuthKIPassword;
     AuthGSSAPICheck3->Checked = FSessionData->AuthGSSAPI;
@@ -254,14 +250,6 @@ void __fastcall TSiteAdvancedDialog::LoadSession()
     // SSH page
     Ssh2LegacyDESCheck->Checked = FSessionData->Ssh2DES;
     CompressionCheck->Checked = FSessionData->Compression;
-    if (FSessionData->SshProt == ssh1only)
-    {
-      SshProtCombo2->ItemIndex = 0;
-    }
-    else
-    {
-      SshProtCombo2->ItemIndex = 1;
-    }
 
     CipherListBox->Items->Clear();
     DebugAssert(CIPHER_NAME_WARN+CIPHER_COUNT-1 == CIPHER_NAME_CHACHA20);
@@ -388,9 +376,6 @@ void __fastcall TSiteAdvancedDialog::LoadSession()
     // Bugs page
     #define LOAD_BUG_COMBO(BUG) \
       ComboAutoSwitchLoad(Bug ## BUG ## Combo, FSessionData->Bug[sb ## BUG])
-    LOAD_BUG_COMBO(Ignore1);
-    LOAD_BUG_COMBO(PlainPW1);
-    LOAD_BUG_COMBO(RSA1);
     LOAD_BUG_COMBO(HMAC2);
     LOAD_BUG_COMBO(DeriveKey2);
     LOAD_BUG_COMBO(RSAPad2);
@@ -444,11 +429,6 @@ void __fastcall TSiteAdvancedDialog::LoadSession()
   UpdateControls();
 }
 //---------------------------------------------------------------------
-TSshProt __fastcall TSiteAdvancedDialog::GetSshProt()
-{
-  return (SshProtCombo2->ItemIndex == 0) ? ssh1only : ssh2only;
-}
-//---------------------------------------------------------------------
 bool TSiteAdvancedDialog::IsDefaultSftpServer()
 {
   return
@@ -466,8 +446,6 @@ void __fastcall TSiteAdvancedDialog::SaveSession(TSessionData * SessionData)
   SessionData->Compression = CompressionCheck->Checked;
   SessionData->Ssh2DES = Ssh2LegacyDESCheck->Checked;
 
-  SessionData->SshProt = GetSshProt();
-
   for (int Index = 0; Index < CIPHER_COUNT; Index++)
   {
     SessionData->Cipher[Index] = (TCipher)CipherListBox->Items->Objects[Index];
@@ -488,7 +466,6 @@ void __fastcall TSiteAdvancedDialog::SaveSession(TSessionData * SessionData)
   // Authentication page
   SessionData->SshNoUserAuth = SshNoUserAuthCheck->Checked;
   SessionData->TryAgent = TryAgentCheck->Checked;
-  SessionData->AuthTIS = AuthTISCheck->Checked;
   SessionData->AuthKI = AuthKICheck->Checked;
   SessionData->AuthKIPassword = AuthKIPasswordCheck->Checked;
   SessionData->AuthGSSAPI = AuthGSSAPICheck3->Checked;
@@ -674,9 +651,6 @@ void __fastcall TSiteAdvancedDialog::SaveSession(TSessionData * SessionData)
 
   // Bugs page
   #define SAVE_BUG_COMBO(BUG) SessionData->Bug[sb ## BUG] = ComboAutoSwitchSave(Bug ## BUG ## Combo)
-  SAVE_BUG_COMBO(Ignore1);
-  SAVE_BUG_COMBO(PlainPW1);
-  SAVE_BUG_COMBO(RSA1);
   SAVE_BUG_COMBO(HMAC2);
   SAVE_BUG_COMBO(DeriveKey2);
   SAVE_BUG_COMBO(RSAPad2);
@@ -872,20 +846,14 @@ void __fastcall TSiteAdvancedDialog::UpdateControls()
 
     // ssh/authentication sheet
     AuthSheet->Enabled = SshProtocol;
-    EnableControl(SshNoUserAuthCheck, (GetSshProt() == ssh2only));
     EnableControl(AuthenticationGroup,
       !SshNoUserAuthCheck->Enabled || !SshNoUserAuthCheck->Checked);
-    EnableControl(AuthTISCheck, AuthenticationGroup->Enabled && (GetSshProt() == ssh1only));
-    EnableControl(AuthKICheck, AuthenticationGroup->Enabled && (GetSshProt() == ssh2only));
     EnableControl(AuthKIPasswordCheck,
-      AuthenticationGroup->Enabled &&
-      ((AuthTISCheck->Enabled && AuthTISCheck->Checked) ||
-       (AuthKICheck->Enabled && AuthKICheck->Checked)));
+      AuthenticationGroup->Enabled && (AuthKICheck->Enabled && AuthKICheck->Checked));
     EnableControl(AuthenticationParamsGroup, AuthenticationGroup->Enabled);
     EnableControl(AgentFwdCheck, AuthenticationParamsGroup->Enabled && TryAgentCheck->Checked);
     EnableControl(PrivateKeyViewButton, PrivateKeyEdit3->Enabled && !PrivateKeyEdit3->Text.IsEmpty());
-    EnableControl(AuthGSSAPICheck3,
-      AuthenticationGroup->Enabled && (GetSshProt() == ssh2only));
+    EnableControl(AuthGSSAPICheck3, AuthenticationGroup->Enabled);
     EnableControl(GSSAPIFwdTGTCheck,
       AuthGSSAPICheck3->Enabled && AuthGSSAPICheck3->Checked);
 
@@ -894,39 +862,15 @@ void __fastcall TSiteAdvancedDialog::UpdateControls()
     EnableControl(CipherUpButton, CipherListBox->ItemIndex > 0);
     EnableControl(CipherDownButton, CipherListBox->ItemIndex >= 0 &&
       CipherListBox->ItemIndex < CipherListBox->Items->Count-1);
-    EnableControl(Ssh2LegacyDESCheck, (GetSshProt() == ssh2only));
 
     // ssh/kex sheet
-    KexSheet->Enabled = SshProtocol && (GetSshProt() == ssh2only) &&
-      (BugRekey2Combo->ItemIndex != 2);
+    KexSheet->Enabled = SshProtocol && (BugRekey2Combo->ItemIndex != 2);
     EnableControl(KexUpButton, KexListBox->ItemIndex > 0);
     EnableControl(KexDownButton, KexListBox->ItemIndex >= 0 &&
       KexListBox->ItemIndex < KexListBox->Items->Count-1);
 
     // ssh/bugs sheet
     BugsSheet->Enabled = SshProtocol;
-    EnableControl(BugIgnore1Combo, (GetSshProt() == ssh1only));
-    EnableControl(BugIgnore1Label, BugIgnore1Combo->Enabled);
-    EnableControl(BugPlainPW1Combo, (GetSshProt() == ssh1only));
-    EnableControl(BugPlainPW1Label, BugPlainPW1Combo->Enabled);
-    EnableControl(BugRSA1Combo, (GetSshProt() == ssh1only));
-    EnableControl(BugRSA1Label, BugRSA1Combo->Enabled);
-    EnableControl(BugHMAC2Combo, (GetSshProt() == ssh2only));
-    EnableControl(BugHMAC2Label, BugHMAC2Combo->Enabled);
-    EnableControl(BugDeriveKey2Combo, (GetSshProt() == ssh2only));
-    EnableControl(BugDeriveKey2Label, BugDeriveKey2Combo->Enabled);
-    EnableControl(BugRSAPad2Combo, (GetSshProt() == ssh2only));
-    EnableControl(BugRSAPad2Label, BugRSAPad2Combo->Enabled);
-    EnableControl(BugPKSessID2Combo, (GetSshProt() == ssh2only));
-    EnableControl(BugPKSessID2Label, BugPKSessID2Combo->Enabled);
-    EnableControl(BugRekey2Combo, (GetSshProt() == ssh2only));
-    EnableControl(BugRekey2Label, BugRekey2Combo->Enabled);
-    EnableControl(BugMaxPkt2Combo, (GetSshProt() == ssh2only));
-    EnableControl(BugMaxPkt2Label, BugMaxPkt2Combo->Enabled);
-    EnableControl(BugIgnore2Combo, (GetSshProt() == ssh2only));
-    EnableControl(BugIgnore2Label, BugIgnore2Combo->Enabled);
-    EnableControl(BugWinAdjCombo, (GetSshProt() == ssh2only));
-    EnableControl(BugWinAdjLabel, BugWinAdjCombo->Enabled);
 
     // connection/proxy sheet
     // this is probaqbly overkill, now we do not allow changing protocol on
@@ -1368,7 +1312,7 @@ void __fastcall TSiteAdvancedDialog::PrivateKeyEdit3AfterDialog(TObject * Sender
   TFilenameEdit * Edit = dynamic_cast<TFilenameEdit *>(Sender);
   if (Name != Edit->Text)
   {
-    VerifyAndConvertKey(Name, GetSshProt(), true);
+    VerifyAndConvertKey(Name, true);
   }
 }
 //---------------------------------------------------------------------------
@@ -1378,9 +1322,9 @@ void __fastcall TSiteAdvancedDialog::FormCloseQuery(TObject * /*Sender*/,
   if (ModalResult == DefaultResult(this))
   {
     // StripPathQuotes should not be needed as we do not feed quotes anymore
-    VerifyKey(StripPathQuotes(PrivateKeyEdit3->Text), GetSshProt());
+    VerifyKey(StripPathQuotes(PrivateKeyEdit3->Text));
     // for tunnel SSH version is not configurable
-    VerifyKey(StripPathQuotes(TunnelPrivateKeyEdit3->Text), ssh2only);
+    VerifyKey(StripPathQuotes(TunnelPrivateKeyEdit3->Text));
     VerifyCertificate(StripPathQuotes(TlsCertificateFileEdit->Text));
     // Particularly for EncryptKey*Edit's
     ExitActiveControl(this);
@@ -1630,7 +1574,7 @@ void __fastcall TSiteAdvancedDialog::PrivateKeyToolsButtonClick(TObject * /*Send
 {
   UnicodeString Dummy;
   PrivateKeyGenerateItem->Enabled = FindTool(PuttygenTool, Dummy);
-  PrivateKeyUploadItem->Enabled = (GetSshProt() == ssh2only) && (NormalizeFSProtocol(FSessionData->FSProtocol) == fsSFTP);
+  PrivateKeyUploadItem->Enabled = (NormalizeFSProtocol(FSessionData->FSProtocol) == fsSFTP);
   MenuPopup(PrivateKeyMenu, PrivateKeyToolsButton);
 }
 //---------------------------------------------------------------------------
@@ -1660,7 +1604,7 @@ void __fastcall TSiteAdvancedDialog::PrivateKeyUploadItemClick(TObject * /*Sende
 void __fastcall TSiteAdvancedDialog::PrivateKeyViewButtonClick(TObject * /*Sender*/)
 {
   UnicodeString FileName = PrivateKeyEdit3->Text;
-  VerifyAndConvertKey(FileName, GetSshProt(), false);
+  VerifyAndConvertKey(FileName, false);
   PrivateKeyEdit3->Text = FileName;
   UnicodeString CommentDummy;
   UnicodeString Line = GetPublicKeyLine(FileName, CommentDummy);

+ 26 - 111
source/forms/SiteAdvanced.dfm

@@ -1988,21 +1988,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
           Left = 0
           Top = 6
           Width = 393
-          Height = 71
+          Height = 46
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Protocol options'
           TabOrder = 0
           DesignSize = (
             393
-            71)
-          object Label37: TLabel
-            Left = 12
-            Top = 42
-            Width = 103
-            Height = 13
-            Caption = 'SSH protocol version:'
-            FocusControl = SshProtCombo2
-          end
+            46)
           object CompressionCheck: TCheckBox
             Left = 16
             Top = 19
@@ -2013,23 +2005,10 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
             TabOrder = 0
             OnClick = DataChange
           end
-          object SshProtCombo2: TComboBox
-            Left = 303
-            Top = 37
-            Width = 80
-            Height = 21
-            Style = csDropDownList
-            Anchors = [akTop, akRight]
-            TabOrder = 1
-            OnChange = DataChange
-            Items.Strings = (
-              '1 (insecure)'
-              '2')
-          end
         end
         object EncryptionGroup: TGroupBox
           Left = 0
-          Top = 83
+          Top = 58
           Width = 393
           Height = 171
           Anchors = [akLeft, akTop, akRight]
@@ -2066,7 +2045,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
             Width = 367
             Height = 17
             Anchors = [akLeft, akTop, akRight]
-            Caption = 'Enable legacy use of single-&DES in SSH-2'
+            Caption = 'Enable legacy use of single-&DES'
             TabOrder = 3
           end
           object CipherUpButton: TButton
@@ -2243,13 +2222,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
           Left = 0
           Top = 32
           Width = 393
-          Height = 117
+          Height = 94
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Authentication options'
           TabOrder = 1
           DesignSize = (
             393
-            117)
+            94)
           object TryAgentCheck: TCheckBox
             Left = 12
             Top = 19
@@ -2260,16 +2239,6 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
             TabOrder = 0
             OnClick = DataChange
           end
-          object AuthTISCheck: TCheckBox
-            Left = 12
-            Top = 88
-            Width = 373
-            Height = 17
-            Anchors = [akLeft, akTop, akRight]
-            Caption = 'Atte&mpt TIS or CryptoCard authentication (SSH-1)'
-            TabOrder = 3
-            OnClick = DataChange
-          end
           object AuthKICheck: TCheckBox
             Left = 12
             Top = 42
@@ -2293,7 +2262,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
         end
         object AuthenticationParamsGroup: TGroupBox
           Left = 0
-          Top = 154
+          Top = 132
           Width = 393
           Height = 120
           Anchors = [akLeft, akTop, akRight]
@@ -2360,7 +2329,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
         end
         object GSSAPIGroup: TGroupBox
           Left = 0
-          Top = 279
+          Top = 258
           Width = 393
           Height = 71
           Anchors = [akLeft, akTop, akRight]
@@ -2405,131 +2374,77 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
           Left = 0
           Top = 6
           Width = 393
-          Height = 289
+          Height = 217
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Detection of known bugs in SSH servers'
           TabOrder = 0
           DesignSize = (
             393
-            289)
-          object BugIgnore1Label: TLabel
-            Left = 12
-            Top = 212
-            Width = 169
-            Height = 13
-            Caption = 'Chokes on SSH-1 &ignore messages:'
-            FocusControl = BugIgnore1Combo
-          end
-          object BugPlainPW1Label: TLabel
-            Left = 12
-            Top = 236
-            Width = 195
-            Height = 13
-            Caption = 'Refuses all SSH-1 pass&word camouflage:'
-            FocusControl = BugPlainPW1Combo
-          end
-          object BugRSA1Label: TLabel
-            Left = 12
-            Top = 260
-            Width = 181
-            Height = 13
-            Caption = 'Chokes on SSH-1 &RSA authentication:'
-            FocusControl = BugRSA1Combo
-          end
+            217)
           object BugHMAC2Label: TLabel
             Left = 12
             Top = 68
-            Width = 154
+            Width = 144
             Height = 13
-            Caption = 'Miscomputes SSH-2 H&MAC keys:'
+            Caption = 'Miscomputes SSH H&MAC keys:'
             FocusControl = BugHMAC2Combo
           end
           object BugDeriveKey2Label: TLabel
             Left = 12
             Top = 92
-            Width = 176
+            Width = 166
             Height = 13
-            Caption = 'Miscomputes SSH-2 &encryption keys:'
+            Caption = 'Miscomputes SSH &encryption keys:'
             FocusControl = BugDeriveKey2Combo
           end
           object BugRSAPad2Label: TLabel
             Left = 12
             Top = 116
-            Width = 210
+            Width = 200
             Height = 13
-            Caption = 'Requires &padding on SSH-2 RSA signatures:'
+            Caption = 'Requires &padding on SSH RSA signatures:'
             FocusControl = BugRSAPad2Combo
           end
           object BugPKSessID2Label: TLabel
             Left = 12
             Top = 140
-            Width = 195
+            Width = 185
             Height = 13
-            Caption = 'Misuses the sessio&n ID in SSH-2 PK auth:'
+            Caption = 'Misuses the sessio&n ID in SSH PK auth:'
             FocusControl = BugPKSessID2Combo
           end
           object BugRekey2Label: TLabel
             Left = 12
             Top = 164
-            Width = 187
+            Width = 177
             Height = 13
-            Caption = 'Handles SSH-2 &key re-exchange badly:'
+            Caption = 'Handles SSH &key re-exchange badly:'
             FocusControl = BugRekey2Combo
           end
           object BugMaxPkt2Label: TLabel
             Left = 12
             Top = 188
-            Width = 176
+            Width = 166
             Height = 13
-            Caption = 'Ignores SSH-2 ma&ximum packet size:'
+            Caption = 'Ignores SSH ma&ximum packet size:'
             FocusControl = BugMaxPkt2Combo
           end
           object BugIgnore2Label: TLabel
             Left = 12
             Top = 20
-            Width = 169
+            Width = 159
             Height = 13
-            Caption = 'Chokes on SSH-&2 ignore messages:'
+            Caption = 'Chokes on SSH i&gnore messages:'
             FocusControl = BugIgnore2Combo
           end
           object BugWinAdjLabel: TLabel
             Left = 12
             Top = 44
-            Width = 212
+            Width = 202
             Height = 13
-            Caption = 'Chokes on WinSCP'#39's SSH-2 '#39'winadj'#39' requests'
+            Caption = 'Chokes on WinSCP'#39's SSH '#39'&winadj'#39' requests'
             FocusControl = BugWinAdjCombo
           end
-          object BugIgnore1Combo: TComboBox
-            Left = 320
-            Top = 207
-            Width = 61
-            Height = 21
-            Style = csDropDownList
-            Anchors = [akTop, akRight]
-            TabOrder = 8
-            OnChange = DataChange
-          end
-          object BugPlainPW1Combo: TComboBox
-            Left = 320
-            Top = 231
-            Width = 61
-            Height = 21
-            Style = csDropDownList
-            Anchors = [akTop, akRight]
-            TabOrder = 9
-            OnChange = DataChange
-          end
-          object BugRSA1Combo: TComboBox
-            Left = 320
-            Top = 255
-            Width = 61
-            Height = 21
-            Style = csDropDownList
-            Anchors = [akTop, akRight]
-            TabOrder = 10
-            OnChange = DataChange
-          end
           object BugHMAC2Combo: TComboBox
             Left = 320
             Top = 63

+ 0 - 10
source/forms/SiteAdvanced.h

@@ -29,7 +29,6 @@ __published:
   TPageControl *PageControl;
   TTabSheet *AdvancedSheet;
   TGroupBox *ProtocolGroup;
-  TLabel *Label37;
   TCheckBox *CompressionCheck;
   TTabSheet *EnvironmentSheet;
   TTabSheet *ScpSheet;
@@ -62,12 +61,6 @@ __published:
   TEdit *ProxyTelnetCommandEdit;
   TTabSheet *BugsSheet;
   TGroupBox *BugsGroupBox;
-  TLabel *BugIgnore1Label;
-  TComboBox *BugIgnore1Combo;
-  TLabel *BugPlainPW1Label;
-  TComboBox *BugPlainPW1Combo;
-  TLabel *BugRSA1Label;
-  TComboBox *BugRSA1Combo;
   TLabel *BugHMAC2Label;
   TComboBox *BugHMAC2Combo;
   TLabel *BugDeriveKey2Label;
@@ -76,7 +69,6 @@ __published:
   TComboBox *BugRSAPad2Combo;
   TTabSheet *AuthSheet;
   TGroupBox *AuthenticationGroup;
-  TCheckBox *AuthTISCheck;
   TCheckBox *AuthKICheck;
   TGroupBox *EncryptionGroup;
   TListBox *CipherListBox;
@@ -252,7 +244,6 @@ __published:
   TLabel *Label4;
   TFilenameEdit *TlsCertificateFileEdit;
   TCheckBox *TrimVMSVersionsCheck;
-  TComboBox *SshProtCombo2;
   TCheckBox *FollowDirectorySymlinksCheck;
   TImageList *ColorImageList120;
   TImageList *ColorImageList144;
@@ -371,7 +362,6 @@ private:
   TProxyMethod __fastcall GetProxyMethod();
   int __fastcall GetFtpProxyLogonType();
   void __fastcall UpdateNavigationTree();
-  TSshProt __fastcall GetSshProt();
   void __fastcall SessionColorChange(TColor Color);
   TTlsVersion __fastcall IndexToTlsVersion(int Index);
   int __fastcall TlsVersionToIndex(TTlsVersion TlsVersion);

+ 0 - 1
source/putty/puttyexp.h

@@ -9,7 +9,6 @@ int is_ssh(Plug * plug);
 int get_ssh_version(Backend * be);
 Seat * get_ssh_seat(Plug * plug);
 #ifdef WINSCP_SSH
-const ssh_cipher * get_cipher(Backend * be);
 const ssh_cipher * get_cscipher(Backend * be);
 const ssh_cipher * get_sccipher(Backend * be);
 #endif

+ 5 - 29
source/putty/ssh.c

@@ -187,12 +187,13 @@ static void ssh_got_ssh_version(struct ssh_version_receiver *rcv,
      * connect_to_host().
      */
     assert(ssh->version == major_version);
+    assert(ssh->version == 2);
 
     old_bpp = ssh->bpp;
     ssh->remote_bugs = ssh_verstring_get_bugs(old_bpp);
 
     if (!ssh->bare_connection) {
-        if (ssh->version == 2) {
+        /*WINSCP if (ssh->version == 2)*/ {
             PacketProtocolLayer *userauth_layer, *transport_child_layer;
 
             /*
@@ -294,19 +295,7 @@ static void ssh_got_ssh_version(struct ssh_version_receiver *rcv,
                 ssh2_userauth_set_transport_layer(userauth_layer,
                                                   ssh->base_layer);
 
-        } else {
-
-            ssh->bpp = ssh1_bpp_new(ssh->logctx);
-            ssh_connect_bpp(ssh);
-
-            connection_layer = ssh1_connection_new(ssh, ssh->conf, &ssh->cl);
-            ssh_connect_ppl(ssh, connection_layer);
-
-            ssh->base_layer = ssh1_login_new(
-                ssh->conf, ssh->savedhost, ssh->savedport, connection_layer);
-            ssh_connect_ppl(ssh, ssh->base_layer);
-
-        }
+        } // WINSCP
 
     } else {
         ssh->bpp = ssh2_bare_bpp_new(ssh->logctx);
@@ -734,7 +723,7 @@ static char *connect_to_host(
     SockAddr *addr;
     const char *err;
     char *loghost;
-    int addressfamily, sshprot;
+    int addressfamily;
 
     ssh_hostport_setup(host, port, ssh->conf,
                        &ssh->savedhost, &ssh->savedport, &loghost);
@@ -811,15 +800,8 @@ static char *connect_to_host(
      * The SSH version number is always fixed (since we no longer support
      * fallback between versions), so set it now.
      */
-    sshprot = conf_get_int(ssh->conf, CONF_sshprot);
-    assert(sshprot == 0 || sshprot == 3);
-    if (sshprot == 0)
-        /* SSH-1 only */
-        ssh->version = 1;
-    if (sshprot == 3 || ssh->bare_connection) {
         /* SSH-2 only */
-        ssh->version = 2;
-    }
+        ssh->version = 2; // WINSCP
 
     /*
      * Set up the initial BPP that will do the version string
@@ -1296,12 +1278,6 @@ Seat * get_ssh_seat(Plug * plug)
   return container_of(plug, Ssh, plug)->seat;
 }
 
-const ssh_cipher * get_cipher(Backend * be)
-{
-  Ssh * ssh = container_of(be, Ssh, backend);
-  return ssh1_bpp_get_cipher(ssh->bpp);
-}
-
 const ssh_cipher * get_cscipher(Backend * be)
 {
   Ssh * ssh = container_of(be, Ssh, backend);

+ 0 - 395
source/putty/ssh1bpp.c

@@ -1,395 +0,0 @@
-/*
- * Binary packet protocol for SSH-1.
- */
-
-#include <assert.h>
-
-#include "putty.h"
-#include "ssh.h"
-#include "sshbpp.h"
-#include "sshcr.h"
-
-struct ssh1_bpp_state {
-    int crState;
-    long len, pad, biglen, length, maxlen;
-    unsigned char *data;
-    uint32_t realcrc, gotcrc;
-    int chunk;
-    PktIn *pktin;
-
-    ssh_cipher *cipher_in, *cipher_out;
-
-    struct crcda_ctx *crcda_ctx;
-    uint8_t iv[8];                     /* for crcda */
-
-    bool pending_compression_request;
-    ssh_compressor *compctx;
-    ssh_decompressor *decompctx;
-
-    BinaryPacketProtocol bpp;
-};
-
-static void ssh1_bpp_free(BinaryPacketProtocol *bpp);
-static void ssh1_bpp_handle_input(BinaryPacketProtocol *bpp);
-static void ssh1_bpp_handle_output(BinaryPacketProtocol *bpp);
-static void ssh1_bpp_queue_disconnect(BinaryPacketProtocol *bpp,
-                                      const char *msg, int category);
-static PktOut *ssh1_bpp_new_pktout(int type);
-
-static const BinaryPacketProtocolVtable ssh1_bpp_vtable = {
-    // WINSCP
-    /*.free =*/ ssh1_bpp_free,
-    /*.handle_input =*/ ssh1_bpp_handle_input,
-    /*.handle_output =*/ ssh1_bpp_handle_output,
-    /*.new_pktout =*/ ssh1_bpp_new_pktout,
-    /*.queue_disconnect =*/ ssh1_bpp_queue_disconnect,
-    /*.packet_size_limit =*/ 0xFFFFFFFF, /* no special limit for this bpp */
-};
-
-BinaryPacketProtocol *ssh1_bpp_new(LogContext *logctx)
-{
-    struct ssh1_bpp_state *s = snew(struct ssh1_bpp_state);
-    memset(s, 0, sizeof(*s));
-    s->bpp.vt = &ssh1_bpp_vtable;
-    s->bpp.logctx = logctx;
-    ssh_bpp_common_setup(&s->bpp);
-    return &s->bpp;
-}
-
-static void ssh1_bpp_free(BinaryPacketProtocol *bpp)
-{
-    struct ssh1_bpp_state *s = container_of(bpp, struct ssh1_bpp_state, bpp);
-    if (s->cipher_in)
-        ssh_cipher_free(s->cipher_in);
-    if (s->cipher_out)
-        ssh_cipher_free(s->cipher_out);
-    if (s->compctx)
-        ssh_compressor_free(s->compctx);
-    if (s->decompctx)
-        ssh_decompressor_free(s->decompctx);
-    if (s->crcda_ctx)
-        crcda_free_context(s->crcda_ctx);
-    sfree(s->pktin);
-    sfree(s);
-}
-
-void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp,
-                         const ssh_cipheralg *cipher,
-                         const void *session_key)
-{
-    struct ssh1_bpp_state *s;
-    assert(bpp->vt == &ssh1_bpp_vtable);
-    s = container_of(bpp, struct ssh1_bpp_state, bpp);
-
-    assert(!s->cipher_in);
-    assert(!s->cipher_out);
-
-    if (cipher) {
-        s->cipher_in = ssh_cipher_new(cipher);
-        s->cipher_out = ssh_cipher_new(cipher);
-        ssh_cipher_setkey(s->cipher_in, session_key);
-        ssh_cipher_setkey(s->cipher_out, session_key);
-
-        assert(!s->crcda_ctx);
-        s->crcda_ctx = crcda_make_context();
-
-        bpp_logevent("Initialised %s encryption", cipher->text_name);
-
-        memset(s->iv, 0, sizeof(s->iv));
-
-        assert(cipher->blksize <= sizeof(s->iv));
-        ssh_cipher_setiv(s->cipher_in, s->iv);
-        ssh_cipher_setiv(s->cipher_out, s->iv);
-    }
-}
-
-void ssh1_bpp_start_compression(BinaryPacketProtocol *bpp)
-{
-    struct ssh1_bpp_state *s;
-    assert(bpp->vt == &ssh1_bpp_vtable);
-    s = container_of(bpp, struct ssh1_bpp_state, bpp);
-
-    assert(!s->compctx);
-    assert(!s->decompctx);
-
-    s->compctx = ssh_compressor_new(&ssh_zlib);
-    s->decompctx = ssh_decompressor_new(&ssh_zlib);
-
-    bpp_logevent("Started zlib (RFC1950) compression");
-}
-
-#define BPP_READ(ptr, len) do                                           \
-    {                                                                   \
-        bool success;                                                   \
-        crMaybeWaitUntilV((success = bufchain_try_fetch_consume(        \
-                               s->bpp.in_raw, ptr, len)) ||             \
-                          s->bpp.input_eof);                            \
-        if (!success)                                                   \
-            goto eof;                                                   \
-        ssh_check_frozen(s->bpp.ssh);                                   \
-    } while (0)
-
-static void ssh1_bpp_handle_input(BinaryPacketProtocol *bpp)
-{
-    struct ssh1_bpp_state *s = container_of(bpp, struct ssh1_bpp_state, bpp);
-
-    crBegin(s->crState);
-
-    while (1) {
-        s->maxlen = 0;
-        s->length = 0;
-
-        {
-            unsigned char lenbuf[4];
-            BPP_READ(lenbuf, 4);
-            s->len = toint(GET_32BIT_MSB_FIRST(lenbuf));
-        }
-
-        if (s->len < 5 || s->len > 262144) { /* SSH1.5-mandated max size */
-            ssh_sw_abort(s->bpp.ssh,
-                         "Out-of-range packet length from remote suggests"
-                         " data stream corruption");
-            crStopV;
-        }
-
-        s->pad = 8 - (s->len % 8);
-        s->biglen = s->len + s->pad;
-        s->length = s->len - 5;
-
-        /*
-         * Allocate the packet to return, now we know its length.
-         */
-        s->pktin = snew_plus(PktIn, s->biglen);
-        s->pktin->qnode.prev = s->pktin->qnode.next = NULL;
-        s->pktin->qnode.on_free_queue = false;
-        s->pktin->type = 0;
-
-        s->maxlen = s->biglen;
-        s->data = snew_plus_get_aux(s->pktin);
-
-        BPP_READ(s->data, s->biglen);
-
-        if (s->cipher_in && detect_attack(s->crcda_ctx,
-                                          s->data, s->biglen, s->iv)) {
-            ssh_sw_abort(s->bpp.ssh,
-                         "Network attack (CRC compensation) detected!");
-            crStopV;
-        }
-        /* Save the last cipher block, to be passed to the next call
-         * to detect_attack */
-        assert(s->biglen >= 8);
-        memcpy(s->iv, s->data + s->biglen - 8, sizeof(s->iv));
-
-        if (s->cipher_in)
-            ssh_cipher_decrypt(s->cipher_in, s->data, s->biglen);
-
-        s->realcrc = crc32_ssh1(make_ptrlen(s->data, s->biglen - 4));
-        s->gotcrc = GET_32BIT_MSB_FIRST(s->data + s->biglen - 4);
-        if (s->gotcrc != s->realcrc) {
-            ssh_sw_abort(s->bpp.ssh, "Incorrect CRC received on packet");
-            crStopV;
-        }
-
-        if (s->decompctx) {
-            unsigned char *decompblk;
-            int decomplen;
-            if (!ssh_decompressor_decompress(
-                    s->decompctx, s->data + s->pad, s->length + 1,
-                    &decompblk, &decomplen)) {
-                ssh_sw_abort(s->bpp.ssh,
-                             "Zlib decompression encountered invalid data");
-                crStopV;
-            }
-
-            if (s->maxlen < s->pad + decomplen) {
-                PktIn *old_pktin = s->pktin;
-
-                s->maxlen = s->pad + decomplen;
-                s->pktin = snew_plus(PktIn, s->maxlen);
-                *s->pktin = *old_pktin; /* structure copy */
-                s->data = snew_plus_get_aux(s->pktin);
-
-                smemclr(old_pktin, s->biglen);
-                sfree(old_pktin);
-            }
-
-            memcpy(s->data + s->pad, decompblk, decomplen);
-            sfree(decompblk);
-            s->length = decomplen - 1;
-        }
-
-        /*
-         * Now we can find the bounds of the semantic content of the
-         * packet, and the initial type byte.
-         */
-        s->data += s->pad;
-        s->pktin->type = *s->data++;
-        BinarySource_INIT(s->pktin, s->data, s->length);
-
-        if (s->bpp.logctx) {
-            logblank_t blanks[MAX_BLANKS];
-            int nblanks = ssh1_censor_packet(
-                s->bpp.pls, s->pktin->type, false,
-                make_ptrlen(s->data, s->length), blanks);
-            log_packet(s->bpp.logctx, PKT_INCOMING, s->pktin->type,
-                       ssh1_pkt_type(s->pktin->type),
-                       get_ptr(s->pktin), get_avail(s->pktin), nblanks, blanks,
-                       NULL, 0, NULL);
-        }
-
-        s->pktin->qnode.formal_size = get_avail(s->pktin);
-        pq_push(&s->bpp.in_pq, s->pktin);
-
-        {
-            int type = s->pktin->type;
-            s->pktin = NULL;
-
-            switch (type) {
-              case SSH1_SMSG_SUCCESS:
-              case SSH1_SMSG_FAILURE:
-                if (s->pending_compression_request) {
-                    /*
-                     * This is the response to
-                     * SSH1_CMSG_REQUEST_COMPRESSION.
-                     */
-                    if (type == SSH1_SMSG_SUCCESS) {
-                        /*
-                         * If the response was positive, start
-                         * compression.
-                         */
-                        ssh1_bpp_start_compression(&s->bpp);
-                    }
-
-                    /*
-                     * Either way, cancel the pending flag, and
-                     * schedule a run of our output side in case we
-                     * had any packets queued up in the meantime.
-                     */
-                    s->pending_compression_request = false;
-                    queue_idempotent_callback(&s->bpp.ic_out_pq);
-                }
-                break;
-            }
-        }
-    }
-
-  eof:
-    if (!s->bpp.expect_close) {
-        ssh_remote_error(s->bpp.ssh,
-                         "Remote side unexpectedly closed network connection");
-    } else {
-        ssh_remote_eof(s->bpp.ssh, "Remote side closed network connection");
-    }
-    return;  /* avoid touching s now it's been freed */
-
-    crFinishV;
-}
-
-static PktOut *ssh1_bpp_new_pktout(int pkt_type)
-{
-    PktOut *pkt = ssh_new_packet();
-    pkt->length = 4 + 8;            /* space for length + max padding */
-    put_byte(pkt, pkt_type);
-    pkt->prefix = pkt->length;
-    pkt->type = pkt_type;
-    pkt->downstream_id = 0;
-    pkt->additional_log_text = NULL;
-    return pkt;
-}
-
-static void ssh1_bpp_format_packet(struct ssh1_bpp_state *s, PktOut *pkt)
-{
-    int pad, biglen, pktoffs;
-    uint32_t crc;
-    int len;
-
-    if (s->bpp.logctx) {
-        ptrlen pktdata = make_ptrlen(pkt->data + pkt->prefix,
-                                     pkt->length - pkt->prefix);
-        logblank_t blanks[MAX_BLANKS];
-        int nblanks = ssh1_censor_packet(
-            s->bpp.pls, pkt->type, true, pktdata, blanks);
-        log_packet(s->bpp.logctx, PKT_OUTGOING, pkt->type,
-                   ssh1_pkt_type(pkt->type),
-                   pktdata.ptr, pktdata.len, nblanks, blanks,
-                   NULL, 0, NULL);
-    }
-
-    if (s->compctx) {
-        unsigned char *compblk;
-        int complen;
-        ssh_compressor_compress(s->compctx, pkt->data + 12, pkt->length - 12,
-                                &compblk, &complen, 0);
-        /* Replace the uncompressed packet data with the compressed
-         * version. */
-        pkt->length = 12;
-        put_data(pkt, compblk, complen);
-        sfree(compblk);
-    }
-
-    put_uint32(pkt, 0); /* space for CRC */
-    len = pkt->length - 4 - 8;  /* len(type+data+CRC) */
-    pad = 8 - (len % 8);
-    pktoffs = 8 - pad;
-    biglen = len + pad;         /* len(padding+type+data+CRC) */
-
-    random_read(pkt->data + pktoffs, 4+8 - pktoffs);
-    crc = crc32_ssh1(
-        make_ptrlen(pkt->data + pktoffs + 4, biglen - 4)); /* all ex len */
-    PUT_32BIT_MSB_FIRST(pkt->data + pktoffs + 4 + biglen - 4, crc);
-    PUT_32BIT_MSB_FIRST(pkt->data + pktoffs, len);
-
-    if (s->cipher_out)
-        ssh_cipher_encrypt(s->cipher_out, pkt->data + pktoffs + 4, biglen);
-
-    bufchain_add(s->bpp.out_raw, pkt->data + pktoffs,
-                 biglen + 4); /* len(length+padding+type+data+CRC) */
-}
-
-static void ssh1_bpp_handle_output(BinaryPacketProtocol *bpp)
-{
-    struct ssh1_bpp_state *s = container_of(bpp, struct ssh1_bpp_state, bpp);
-    PktOut *pkt;
-
-    if (s->pending_compression_request) {
-        /*
-         * Don't send any output packets while we're awaiting a
-         * response to SSH1_CMSG_REQUEST_COMPRESSION, because if they
-         * cross over in transit with the responding SSH1_CMSG_SUCCESS
-         * then the other end could decode them with the wrong
-         * compression settings.
-         */
-        return;
-    }
-
-    while ((pkt = pq_pop(&s->bpp.out_pq)) != NULL) {
-        int type = pkt->type;
-        ssh1_bpp_format_packet(s, pkt);
-        ssh_free_pktout(pkt);
-
-        if (type == SSH1_CMSG_REQUEST_COMPRESSION) {
-            /*
-             * When we see the actual compression request go past, set
-             * the pending flag, and stop processing packets this
-             * time.
-             */
-            s->pending_compression_request = true;
-            break;
-        }
-    }
-}
-
-static void ssh1_bpp_queue_disconnect(BinaryPacketProtocol *bpp,
-                                      const char *msg, int category)
-{
-    PktOut *pkt = ssh_bpp_new_pktout(bpp, SSH1_MSG_DISCONNECT);
-    put_stringz(pkt, msg);
-    pq_push(&bpp->out_pq, pkt);
-}
-
-#ifdef MPEXT
-const ssh_cipher * ssh1_bpp_get_cipher(BinaryPacketProtocol *bpp)
-{
-    return container_of(bpp, struct ssh1_bpp_state, bpp)->cipher_in; // cipher_out should be the same
-}
-#endif

+ 0 - 76
source/putty/ssh1censor.c

@@ -1,76 +0,0 @@
-/*
- * Packet-censoring code for SSH-1, used to identify sensitive fields
- * like passwords so that the logging system can avoid writing them
- * into log files.
- */
-
-#include <assert.h>
-
-#include "putty.h"
-#include "ssh.h"
-
-int ssh1_censor_packet(
-    const PacketLogSettings *pls, int type, bool sender_is_client,
-    ptrlen pkt, logblank_t *blanks)
-{
-    int nblanks = 0;
-    ptrlen str;
-    BinarySource src[1];
-
-    BinarySource_BARE_INIT_PL(src, pkt);
-
-    if (pls->omit_data &&
-        (type == SSH1_SMSG_STDOUT_DATA ||
-         type == SSH1_SMSG_STDERR_DATA ||
-         type == SSH1_CMSG_STDIN_DATA ||
-         type == SSH1_MSG_CHANNEL_DATA)) {
-        /* "Session data" packets - omit the data string. */
-        if (type == SSH1_MSG_CHANNEL_DATA)
-            get_uint32(src);           /* skip channel id */
-        str = get_string(src);
-        if (!get_err(src)) {
-            assert(nblanks < MAX_BLANKS);
-            blanks[nblanks].offset = src->pos - str.len;
-            blanks[nblanks].type = PKTLOG_OMIT;
-            blanks[nblanks].len = str.len;
-            nblanks++;
-        }
-    }
-
-    if (sender_is_client && pls->omit_passwords) {
-        if (type == SSH1_CMSG_AUTH_PASSWORD ||
-            type == SSH1_CMSG_AUTH_TIS_RESPONSE ||
-            type == SSH1_CMSG_AUTH_CCARD_RESPONSE) {
-            /* If this is a password or similar packet, blank the
-             * password(s). */
-            assert(nblanks < MAX_BLANKS);
-            blanks[nblanks].offset = 0;
-            blanks[nblanks].len = pkt.len;
-            blanks[nblanks].type = PKTLOG_BLANK;
-            nblanks++;
-        } else if (type == SSH1_CMSG_X11_REQUEST_FORWARDING) {
-            /*
-             * If this is an X forwarding request packet, blank the
-             * fake auth data.
-             *
-             * Note that while we blank the X authentication data
-             * here, we don't take any special action to blank the
-             * start of an X11 channel, so using MIT-MAGIC-COOKIE-1
-             * and actually opening an X connection without having
-             * session blanking enabled is likely to leak your cookie
-             * into the log.
-             */
-            get_string(src);              /* skip protocol name */
-            str = get_string(src);
-            if (!get_err(src)) {
-                assert(nblanks < MAX_BLANKS);
-                blanks[nblanks].offset = src->pos - str.len;
-                blanks[nblanks].type = PKTLOG_BLANK;
-                blanks[nblanks].len = str.len;
-                nblanks++;
-            }
-        }
-    }
-
-    return nblanks;
-}

+ 0 - 558
source/putty/ssh1connection-client.c

@@ -1,558 +0,0 @@
-/*
- * Client-specific parts of the SSH-1 connection layer.
- */
-
-#include <assert.h>
-
-#include "putty.h"
-#include "ssh.h"
-#include "sshbpp.h"
-#include "sshppl.h"
-#include "sshchan.h"
-#include "sshcr.h"
-#include "ssh1connection.h"
-
-// WINSCP
-#define queue_toplevel_callback(FN, CTX) queue_toplevel_callback(get_log_callback_set(CTX->cl.logctx), FN, CTX)
-
-void ssh1_connection_direction_specific_setup(
-    struct ssh1_connection_state *s)
-{
-    if (!s->mainchan) {
-        /*
-         * Start up the main session, by telling mainchan.c to do it
-         * all just as it would in SSH-2, and translating those
-         * concepts to SSH-1's non-channel-shaped idea of the main
-         * session.
-         */
-        s->mainchan = mainchan_new(
-            &s->ppl, &s->cl, s->conf, s->term_width, s->term_height,
-            false /* is_simple */, NULL);
-    }
-}
-
-typedef void (*sf_handler_fn_t)(struct ssh1_connection_state *s,
-                                bool success, void *ctx);
-
-struct outstanding_succfail {
-    sf_handler_fn_t handler;
-    void *ctx;
-    struct outstanding_succfail *next;
-
-    /*
-     * The 'trivial' flag is set if this handler is in response to a
-     * request for which the SSH-1 protocol doesn't actually specify a
-     * response packet. The client of this system (mainchan.c) will
-     * expect to get an acknowledgment regardless, so we arrange to
-     * send that ack immediately after the rest of the queue empties.
-     */
-    bool trivial;
-};
-
-static void ssh1_connection_process_trivial_succfails(void *vs);
-
-static void ssh1_queue_succfail_handler(
-    struct ssh1_connection_state *s, sf_handler_fn_t handler, void *ctx,
-    bool trivial)
-{
-    struct outstanding_succfail *osf = snew(struct outstanding_succfail);
-    osf->handler = handler;
-    osf->ctx = ctx;
-    osf->trivial = trivial;
-    osf->next = NULL;
-    if (s->succfail_tail)
-        s->succfail_tail->next = osf;
-    else
-        s->succfail_head = osf;
-    s->succfail_tail = osf;
-
-    /* In case this one was trivial and the queue was already empty,
-     * we should make sure we run the handler promptly, and the
-     * easiest way is to queue it anyway and then run a trivials pass
-     * by callback. */
-    queue_toplevel_callback(ssh1_connection_process_trivial_succfails, s);
-}
-
-static void ssh1_connection_process_succfail(
-    struct ssh1_connection_state *s, bool success)
-{
-    struct outstanding_succfail *prevhead = s->succfail_head;
-    s->succfail_head = s->succfail_head->next;
-    if (!s->succfail_head)
-        s->succfail_tail = NULL;
-    prevhead->handler(s, success, prevhead->ctx);
-    sfree(prevhead);
-}
-
-static void ssh1_connection_process_trivial_succfails(void *vs)
-{
-    struct ssh1_connection_state *s = (struct ssh1_connection_state *)vs;
-    while (s->succfail_head && s->succfail_head->trivial)
-        ssh1_connection_process_succfail(s, true);
-}
-
-bool ssh1_handle_direction_specific_packet(
-    struct ssh1_connection_state *s, PktIn *pktin)
-{
-    PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
-
-    PktOut *pktout;
-    struct ssh1_channel *c;
-    unsigned remid;
-    struct ssh_rportfwd pf, *pfp;
-    ptrlen host, data;
-    int port;
-
-    switch (pktin->type) {
-      case SSH1_SMSG_SUCCESS:
-      case SSH1_SMSG_FAILURE:
-        if (!s->succfail_head) {
-            ssh_remote_error(s->ppl.ssh,
-                             "Received %s with no outstanding request",
-                             ssh1_pkt_type(pktin->type));
-            return true;
-        }
-
-        ssh1_connection_process_succfail(
-            s, pktin->type == SSH1_SMSG_SUCCESS);
-        queue_toplevel_callback(
-            ssh1_connection_process_trivial_succfails, s);
-
-        return true;
-
-      case SSH1_SMSG_X11_OPEN:
-        remid = get_uint32(pktin);
-
-        /* Refuse if X11 forwarding is disabled. */
-        if (!s->X11_fwd_enabled) {
-            pktout = ssh_bpp_new_pktout(
-                s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_FAILURE);
-            put_uint32(pktout, remid);
-            pq_push(s->ppl.out_pq, pktout);
-            ppl_logevent("Rejected X11 connect request");
-        } else {
-            c = snew(struct ssh1_channel);
-            c->connlayer = s;
-            ssh1_channel_init(c);
-            c->remoteid = remid;
-            c->chan = x11_new_channel(s->x11authtree, &c->sc,
-                                      NULL, -1, false);
-            c->remoteid = remid;
-            c->halfopen = false;
-
-            pktout = ssh_bpp_new_pktout(
-                s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION);
-            put_uint32(pktout, c->remoteid);
-            put_uint32(pktout, c->localid);
-            pq_push(s->ppl.out_pq, pktout);
-            ppl_logevent("Opened X11 forward channel");
-        }
-
-        return true;
-
-      case SSH1_SMSG_AGENT_OPEN:
-        remid = get_uint32(pktin);
-
-        /* Refuse if agent forwarding is disabled. */
-        if (!ssh_agent_forwarding_permitted(&s->cl)) {
-            pktout = ssh_bpp_new_pktout(
-                s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_FAILURE);
-            put_uint32(pktout, remid);
-            pq_push(s->ppl.out_pq, pktout);
-        } else {
-            c = snew(struct ssh1_channel);
-            c->connlayer = s;
-            ssh1_channel_init(c);
-            c->remoteid = remid;
-            c->halfopen = false;
-
-            /*
-             * If possible, make a stream-oriented connection to the
-             * agent and set up an ordinary port-forwarding type
-             * channel over it.
-             */
-            { // WINSCP
-            Plug *plug;
-            Channel *ch = portfwd_raw_new(&s->cl, &plug, true);
-            Socket *skt = agent_connect(plug);
-            if (!sk_socket_error(skt)) {
-                portfwd_raw_setup(ch, skt, &c->sc);
-                c->chan = ch;
-            } else {
-                portfwd_raw_free(ch);
-
-                /*
-                 * Otherwise, fall back to the old-fashioned system of
-                 * parsing the forwarded data stream ourselves for
-                 * message boundaries, and passing each individual
-                 * message to the one-off agent_query().
-                 */
-                c->chan = agentf_new(&c->sc);
-            }
-
-            pktout = ssh_bpp_new_pktout(
-                s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION);
-            put_uint32(pktout, c->remoteid);
-            put_uint32(pktout, c->localid);
-            pq_push(s->ppl.out_pq, pktout);
-            } // WINSCP
-        }
-
-        return true;
-
-      case SSH1_MSG_PORT_OPEN:
-        remid = get_uint32(pktin);
-        host = get_string(pktin);
-        port = toint(get_uint32(pktin));
-
-        pf.dhost = mkstr(host);
-        pf.dport = port;
-        pfp = find234(s->rportfwds, &pf, NULL);
-
-        if (!pfp) {
-            ppl_logevent("Rejected remote port open request for %s:%d",
-                         pf.dhost, port);
-            pktout = ssh_bpp_new_pktout(
-                s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_FAILURE);
-            put_uint32(pktout, remid);
-            pq_push(s->ppl.out_pq, pktout);
-        } else {
-            char *err;
-
-            c = snew(struct ssh1_channel);
-            c->connlayer = s;
-            ppl_logevent("Received remote port open request for %s:%d",
-                         pf.dhost, port);
-            err = portfwdmgr_connect(
-                s->portfwdmgr, &c->chan, pf.dhost, port,
-                &c->sc, pfp->addressfamily);
-
-            if (err) {
-                ppl_logevent("Port open failed: %s", err);
-                sfree(err);
-                ssh1_channel_free(c);
-                pktout = ssh_bpp_new_pktout(
-                    s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_FAILURE);
-                put_uint32(pktout, remid);
-                pq_push(s->ppl.out_pq, pktout);
-            } else {
-                ssh1_channel_init(c);
-                c->remoteid = remid;
-                c->halfopen = false;
-                pktout = ssh_bpp_new_pktout(
-                    s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION);
-                put_uint32(pktout, c->remoteid);
-                put_uint32(pktout, c->localid);
-                pq_push(s->ppl.out_pq, pktout);
-                ppl_logevent("Forwarded port opened successfully");
-            }
-        }
-
-        sfree(pf.dhost);
-
-        return true;
-
-      case SSH1_SMSG_STDOUT_DATA:
-      case SSH1_SMSG_STDERR_DATA:
-        data = get_string(pktin);
-        if (!get_err(pktin)) {
-            int bufsize = seat_output(
-                s->ppl.seat, pktin->type == SSH1_SMSG_STDERR_DATA,
-                data.ptr, data.len);
-            if (!s->stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
-                s->stdout_throttling = true;
-                ssh_throttle_conn(s->ppl.ssh, +1);
-            }
-        }
-
-        return true;
-
-      case SSH1_SMSG_EXIT_STATUS: {
-        int exitcode = get_uint32(pktin);
-        ppl_logevent("Server sent command exit status %d", exitcode);
-        ssh_got_exitcode(s->ppl.ssh, exitcode);
-
-        s->session_terminated = true;
-        return true;
-      }
-
-      default:
-        return false;
-    }
-}
-
-static void ssh1mainchan_succfail_wantreply(struct ssh1_connection_state *s,
-                                            bool success, void *ctx)
-{
-    chan_request_response(s->mainchan_chan, success);
-}
-
-static void ssh1mainchan_succfail_nowantreply(struct ssh1_connection_state *s,
-                                              bool success, void *ctx)
-{
-}
-
-static void ssh1mainchan_queue_response(struct ssh1_connection_state *s,
-                                        bool want_reply, bool trivial)
-{
-    sf_handler_fn_t handler = (want_reply ? ssh1mainchan_succfail_wantreply :
-                               ssh1mainchan_succfail_nowantreply);
-    ssh1_queue_succfail_handler(s, handler, NULL, trivial);
-}
-
-static void ssh1mainchan_request_x11_forwarding(
-    SshChannel *sc, bool want_reply, const char *authproto,
-    const char *authdata, int screen_number, bool oneshot)
-{
-    struct ssh1_connection_state *s =
-        container_of(sc, struct ssh1_connection_state, mainchan_sc);
-    PktOut *pktout;
-
-    pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_X11_REQUEST_FORWARDING);
-    put_stringz(pktout, authproto);
-    put_stringz(pktout, authdata);
-    if (s->local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER)
-        put_uint32(pktout, screen_number);
-    pq_push(s->ppl.out_pq, pktout);
-
-    ssh1mainchan_queue_response(s, want_reply, false);
-}
-
-static void ssh1mainchan_request_agent_forwarding(
-    SshChannel *sc, bool want_reply)
-{
-    struct ssh1_connection_state *s =
-        container_of(sc, struct ssh1_connection_state, mainchan_sc);
-    PktOut *pktout;
-
-    pktout = ssh_bpp_new_pktout(
-        s->ppl.bpp, SSH1_CMSG_AGENT_REQUEST_FORWARDING);
-    pq_push(s->ppl.out_pq, pktout);
-
-    ssh1mainchan_queue_response(s, want_reply, false);
-}
-
-static void ssh1mainchan_request_pty(
-    SshChannel *sc, bool want_reply, Conf *conf, int w, int h)
-{
-    struct ssh1_connection_state *s =
-        container_of(sc, struct ssh1_connection_state, mainchan_sc);
-    PktOut *pktout;
-
-    pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_REQUEST_PTY);
-    put_stringz(pktout, conf_get_str(s->conf, CONF_termtype));
-    put_uint32(pktout, h);
-    put_uint32(pktout, w);
-    put_uint32(pktout, 0); /* width in pixels */
-    put_uint32(pktout, 0); /* height in pixels */
-    write_ttymodes_to_packet(
-        BinarySink_UPCAST(pktout), 1,
-        get_ttymodes_from_conf(s->ppl.seat, conf));
-    pq_push(s->ppl.out_pq, pktout);
-
-    ssh1mainchan_queue_response(s, want_reply, false);
-}
-
-static bool ssh1mainchan_send_env_var(
-    SshChannel *sc, bool want_reply, const char *var, const char *value)
-{
-    return false;              /* SSH-1 doesn't support this at all */
-}
-
-static void ssh1mainchan_start_shell(SshChannel *sc, bool want_reply)
-{
-    struct ssh1_connection_state *s =
-        container_of(sc, struct ssh1_connection_state, mainchan_sc);
-    PktOut *pktout;
-
-    pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_EXEC_SHELL);
-    pq_push(s->ppl.out_pq, pktout);
-
-    ssh1mainchan_queue_response(s, want_reply, true);
-}
-
-static void ssh1mainchan_start_command(
-    SshChannel *sc, bool want_reply, const char *command)
-{
-    struct ssh1_connection_state *s =
-        container_of(sc, struct ssh1_connection_state, mainchan_sc);
-    PktOut *pktout;
-
-    pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_EXEC_CMD);
-    put_stringz(pktout, command);
-    pq_push(s->ppl.out_pq, pktout);
-
-    ssh1mainchan_queue_response(s, want_reply, true);
-}
-
-static bool ssh1mainchan_start_subsystem(
-    SshChannel *sc, bool want_reply, const char *subsystem)
-{
-    return false;              /* SSH-1 doesn't support this at all */
-}
-
-static bool ssh1mainchan_send_serial_break(
-    SshChannel *sc, bool want_reply, int length)
-{
-    return false;              /* SSH-1 doesn't support this at all */
-}
-
-static bool ssh1mainchan_send_signal(
-    SshChannel *sc, bool want_reply, const char *signame)
-{
-    return false;              /* SSH-1 doesn't support this at all */
-}
-
-static void ssh1mainchan_send_terminal_size_change(
-    SshChannel *sc, int w, int h)
-{
-    struct ssh1_connection_state *s =
-        container_of(sc, struct ssh1_connection_state, mainchan_sc);
-    PktOut *pktout;
-
-    pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_WINDOW_SIZE);
-    put_uint32(pktout, h);
-    put_uint32(pktout, w);
-    put_uint32(pktout, 0); /* width in pixels */
-    put_uint32(pktout, 0); /* height in pixels */
-    pq_push(s->ppl.out_pq, pktout);
-}
-
-static void ssh1mainchan_hint_channel_is_simple(SshChannel *sc)
-{
-}
-
-static size_t ssh1mainchan_write(
-    SshChannel *sc, bool is_stderr, const void *data, size_t len)
-{
-    struct ssh1_connection_state *s =
-        container_of(sc, struct ssh1_connection_state, mainchan_sc);
-    PktOut *pktout;
-
-    pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_STDIN_DATA);
-    put_string(pktout, data, len);
-    pq_push(s->ppl.out_pq, pktout);
-
-    return 0;
-}
-
-static void ssh1mainchan_write_eof(SshChannel *sc)
-{
-    struct ssh1_connection_state *s =
-        container_of(sc, struct ssh1_connection_state, mainchan_sc);
-    PktOut *pktout;
-
-    pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_EOF);
-    pq_push(s->ppl.out_pq, pktout);
-}
-
-static const SshChannelVtable ssh1mainchan_vtable = {
-    // WINSCP
-    /*.write =*/ ssh1mainchan_write,
-    /*.write_eof =*/ ssh1mainchan_write_eof,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // WINSCP
-    /*.request_x11_forwarding =*/ ssh1mainchan_request_x11_forwarding,
-    /*.request_agent_forwarding =*/ ssh1mainchan_request_agent_forwarding,
-    /*.request_pty =*/ ssh1mainchan_request_pty,
-    /*.send_env_var =*/ ssh1mainchan_send_env_var,
-    /*.start_shell =*/ ssh1mainchan_start_shell,
-    /*.start_command =*/ ssh1mainchan_start_command,
-    /*.start_subsystem =*/ ssh1mainchan_start_subsystem,
-    /*.send_serial_break =*/ ssh1mainchan_send_serial_break,
-    /*.send_signal =*/ ssh1mainchan_send_signal,
-    /*.send_terminal_size_change =*/ ssh1mainchan_send_terminal_size_change,
-    /*.hint_channel_is_simple =*/ ssh1mainchan_hint_channel_is_simple,
-    /* other methods are NULL */
-};
-
-static void ssh1_session_confirm_callback(void *vctx)
-{
-    struct ssh1_connection_state *s = (struct ssh1_connection_state *)vctx;
-    chan_open_confirmation(s->mainchan_chan);
-}
-
-SshChannel *ssh1_session_open(ConnectionLayer *cl, Channel *chan)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-    s->mainchan_sc.vt = &ssh1mainchan_vtable;
-    s->mainchan_sc.cl = &s->cl;
-    s->mainchan_chan = chan;
-    queue_toplevel_callback(ssh1_session_confirm_callback, s);
-    return &s->mainchan_sc;
-}
-
-static void ssh1_rportfwd_response(struct ssh1_connection_state *s,
-                                   bool success, void *ctx)
-{
-    PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
-    struct ssh_rportfwd *rpf = (struct ssh_rportfwd *)ctx;
-
-    if (success) {
-        ppl_logevent("Remote port forwarding from %s enabled",
-                     rpf->log_description);
-    } else {
-        ppl_logevent("Remote port forwarding from %s refused",
-                     rpf->log_description);
-
-        { // WINSCP
-        struct ssh_rportfwd *realpf = del234(s->rportfwds, rpf);
-        assert(realpf == rpf);
-        portfwdmgr_close(s->portfwdmgr, rpf->pfr);
-        free_rportfwd(rpf);
-        } // WINSCP
-    }
-}
-
-struct ssh_rportfwd *ssh1_rportfwd_alloc(
-    ConnectionLayer *cl,
-    const char *shost, int sport, const char *dhost, int dport,
-    int addressfamily, const char *log_description, PortFwdRecord *pfr,
-    ssh_sharing_connstate *share_ctx)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-    struct ssh_rportfwd *rpf = snew(struct ssh_rportfwd);
-
-    rpf->shost = dupstr(shost);
-    rpf->sport = sport;
-    rpf->dhost = dupstr(dhost);
-    rpf->dport = dport;
-    rpf->addressfamily = addressfamily;
-    rpf->log_description = dupstr(log_description);
-    rpf->pfr = pfr;
-
-    if (add234(s->rportfwds, rpf) != rpf) {
-        free_rportfwd(rpf);
-        return NULL;
-    }
-
-    { // WINSCP
-    PktOut *pktout = ssh_bpp_new_pktout(
-        s->ppl.bpp, SSH1_CMSG_PORT_FORWARD_REQUEST);
-    put_uint32(pktout, rpf->sport);
-    put_stringz(pktout, rpf->dhost);
-    put_uint32(pktout, rpf->dport);
-    pq_push(s->ppl.out_pq, pktout);
-    } // WINSCP
-
-    ssh1_queue_succfail_handler(s, ssh1_rportfwd_response, rpf, false);
-
-    return rpf;
-}
-
-SshChannel *ssh1_serverside_x11_open(
-    ConnectionLayer *cl, Channel *chan, const SocketPeerInfo *pi)
-{
-    unreachable("Should never be called in the client");
-}
-
-SshChannel *ssh1_serverside_agent_open(ConnectionLayer *cl, Channel *chan)
-{
-    unreachable("Should never be called in the client");
-}
-
-bool ssh1_connection_need_antispoof_prompt(struct ssh1_connection_state *s)
-{
-    return !seat_set_trust_status(s->ppl.seat, false);
-}

+ 0 - 851
source/putty/ssh1connection.c

@@ -1,851 +0,0 @@
-/*
- * Packet protocol layer for the SSH-1 'connection protocol', i.e.
- * everything after authentication finishes.
- */
-
-#include <assert.h>
-
-#include "putty.h"
-#include "ssh.h"
-#include "sshbpp.h"
-#include "sshppl.h"
-#include "sshchan.h"
-#include "sshcr.h"
-#include "ssh1connection.h"
-
-// WINSCP
-#define queue_toplevel_callback(FN, CTX) queue_toplevel_callback(get_log_callback_set(CTX->cl.logctx), FN, CTX)
-
-static int ssh1_rportfwd_cmp(void *av, void *bv)
-{
-    struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
-    struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
-    int i;
-    if ( (i = strcmp(a->dhost, b->dhost)) != 0)
-        return i < 0 ? -1 : +1;
-    if (a->dport > b->dport)
-        return +1;
-    if (a->dport < b->dport)
-        return -1;
-    return 0;
-}
-
-static void ssh1_connection_free(PacketProtocolLayer *);
-static void ssh1_connection_process_queue(PacketProtocolLayer *);
-static void ssh1_connection_special_cmd(PacketProtocolLayer *ppl,
-                                        SessionSpecialCode code, int arg);
-static bool ssh1_connection_want_user_input(PacketProtocolLayer *ppl);
-static void ssh1_connection_got_user_input(PacketProtocolLayer *ppl);
-static void ssh1_connection_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
-static unsigned int ssh1_connection_winscp_query(PacketProtocolLayer *ppl, int query);
-
-static const PacketProtocolLayerVtable ssh1_connection_vtable = {
-    // WINSCP
-    /*.free =*/ ssh1_connection_free,
-    /*.process_queue =*/ ssh1_connection_process_queue,
-    /*.get_specials =*/ ssh1_common_get_specials,
-    /*.special_cmd =*/ ssh1_connection_special_cmd,
-    /*.want_user_input =*/ ssh1_connection_want_user_input,
-    /*.got_user_input =*/ ssh1_connection_got_user_input,
-    /*.reconfigure =*/ ssh1_connection_reconfigure,
-    /*.queued_data_size =*/ ssh_ppl_default_queued_data_size,
-    /*.name =*/ NULL, /* no layer names in SSH-1 */
-    ssh1_connection_winscp_query,
-};
-
-static void ssh1_rportfwd_remove(
-    ConnectionLayer *cl, struct ssh_rportfwd *rpf);
-static SshChannel *ssh1_lportfwd_open(
-    ConnectionLayer *cl, const char *hostname, int port,
-    const char *description, const SocketPeerInfo *pi, Channel *chan);
-static struct X11FakeAuth *ssh1_add_x11_display(
-    ConnectionLayer *cl, int authtype, struct X11Display *disp);
-static bool ssh1_agent_forwarding_permitted(ConnectionLayer *cl);
-static void ssh1_terminal_size(ConnectionLayer *cl, int width, int height);
-static void ssh1_stdout_unthrottle(ConnectionLayer *cl, size_t bufsize);
-static size_t ssh1_stdin_backlog(ConnectionLayer *cl);
-static void ssh1_throttle_all_channels(ConnectionLayer *cl, bool throttled);
-static bool ssh1_ldisc_option(ConnectionLayer *cl, int option);
-static void ssh1_set_ldisc_option(ConnectionLayer *cl, int option, bool value);
-static void ssh1_enable_x_fwd(ConnectionLayer *cl);
-static void ssh1_set_wants_user_input(ConnectionLayer *cl, bool wanted);
-
-static const ConnectionLayerVtable ssh1_connlayer_vtable = {
-    // WINSCP
-    /*.rportfwd_alloc =*/ ssh1_rportfwd_alloc,
-    /*.rportfwd_remove =*/ ssh1_rportfwd_remove,
-    /*.lportfwd_open =*/ ssh1_lportfwd_open,
-    /*.session_open =*/ ssh1_session_open,
-    /*.serverside_x11_open =*/ ssh1_serverside_x11_open,
-    /*.serverside_agent_open =*/ ssh1_serverside_agent_open,
-    /*.add_x11_display =*/ ssh1_add_x11_display,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, // WINSCP
-    /*.agent_forwarding_permitted =*/ ssh1_agent_forwarding_permitted,
-    /*.terminal_size =*/ ssh1_terminal_size,
-    /*.stdout_unthrottle =*/ ssh1_stdout_unthrottle,
-    /*.stdin_backlog =*/ ssh1_stdin_backlog,
-    /*.throttle_all_channels =*/ ssh1_throttle_all_channels,
-    /*.ldisc_option =*/ ssh1_ldisc_option,
-    /*.set_ldisc_option =*/ ssh1_set_ldisc_option,
-    /*.enable_x_fwd =*/ ssh1_enable_x_fwd,
-    /*.set_wants_user_input =*/ ssh1_set_wants_user_input,
-    /* other methods are NULL */
-};
-
-static size_t ssh1channel_write(
-    SshChannel *c, bool is_stderr, const void *buf, size_t len);
-static void ssh1channel_write_eof(SshChannel *c);
-static void ssh1channel_initiate_close(SshChannel *c, const char *err);
-static void ssh1channel_unthrottle(SshChannel *c, size_t bufsize);
-static Conf *ssh1channel_get_conf(SshChannel *c);
-static void ssh1channel_window_override_removed(SshChannel *c) { /* ignore */ }
-
-static const SshChannelVtable ssh1channel_vtable = {
-    // WINSCP
-    /*.write =*/ ssh1channel_write,
-    /*.write_eof =*/ ssh1channel_write_eof,
-    /*.initiate_close =*/ ssh1channel_initiate_close,
-    /*.unthrottle =*/ ssh1channel_unthrottle,
-    /*.get_conf =*/ ssh1channel_get_conf,
-    /*.window_override_removed =*/ ssh1channel_window_override_removed,
-    /* everything else is NULL */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // WINSCP
-};
-
-static void ssh1_channel_try_eof(struct ssh1_channel *c);
-static void ssh1_channel_close_local(struct ssh1_channel *c,
-                                     const char *reason);
-static void ssh1_channel_destroy(struct ssh1_channel *c);
-static void ssh1_channel_check_close(struct ssh1_channel *c);
-
-static int ssh1_channelcmp(void *av, void *bv)
-{
-    const struct ssh1_channel *a = (const struct ssh1_channel *) av;
-    const struct ssh1_channel *b = (const struct ssh1_channel *) bv;
-    if (a->localid < b->localid)
-        return -1;
-    if (a->localid > b->localid)
-        return +1;
-    return 0;
-}
-
-static int ssh1_channelfind(void *av, void *bv)
-{
-    const unsigned *a = (const unsigned *) av;
-    const struct ssh1_channel *b = (const struct ssh1_channel *) bv;
-    if (*a < b->localid)
-        return -1;
-    if (*a > b->localid)
-        return +1;
-    return 0;
-}
-
-void ssh1_channel_free(struct ssh1_channel *c)
-{
-    if (c->chan)
-        chan_free(c->chan);
-    sfree(c);
-}
-
-PacketProtocolLayer *ssh1_connection_new(
-    Ssh *ssh, Conf *conf, ConnectionLayer **cl_out)
-{
-    struct ssh1_connection_state *s = snew(struct ssh1_connection_state);
-    memset(s, 0, sizeof(*s));
-    s->ppl.vt = &ssh1_connection_vtable;
-
-    s->conf = conf_copy(conf);
-
-    s->channels = newtree234(ssh1_channelcmp);
-
-    s->x11authtree = newtree234(x11_authcmp);
-
-    /* Need to get the log context for s->cl now, because we won't be
-     * helpfully notified when a copy is written into s->ppl by our
-     * owner. */
-    s->cl.vt = &ssh1_connlayer_vtable;
-    s->cl.logctx = ssh_get_logctx(ssh);
-
-    s->portfwdmgr = portfwdmgr_new(&s->cl);
-    s->rportfwds = newtree234(ssh1_rportfwd_cmp);
-
-    *cl_out = &s->cl;
-    return &s->ppl;
-}
-
-static void ssh1_connection_free(PacketProtocolLayer *ppl)
-{
-    struct ssh1_connection_state *s =
-        container_of(ppl, struct ssh1_connection_state, ppl);
-    struct X11FakeAuth *auth;
-    struct ssh1_channel *c;
-    struct ssh_rportfwd *rpf;
-
-    conf_free(s->conf);
-
-    while ((c = delpos234(s->channels, 0)) != NULL)
-        ssh1_channel_free(c);
-    freetree234(s->channels);
-    if (s->mainchan_chan)
-        chan_free(s->mainchan_chan);
-
-    if (s->x11disp)
-        x11_free_display(s->x11disp);
-    while ((auth = delpos234(s->x11authtree, 0)) != NULL)
-        x11_free_fake_auth(auth);
-    freetree234(s->x11authtree);
-
-    while ((rpf = delpos234(s->rportfwds, 0)) != NULL)
-        free_rportfwd(rpf);
-    freetree234(s->rportfwds);
-    portfwdmgr_free(s->portfwdmgr);
-
-    if (s->antispoof_prompt)
-        free_prompts(s->antispoof_prompt);
-
-    delete_callbacks_for_context(get_seat_callback_set(ppl->seat), s);
-
-    sfree(s);
-}
-
-void ssh1_connection_set_protoflags(PacketProtocolLayer *ppl,
-                                    int local, int remote)
-{
-    pinitassert(ppl->vt == &ssh1_connection_vtable);
-    struct ssh1_connection_state *s =
-        container_of(ppl, struct ssh1_connection_state, ppl);
-    s->local_protoflags = local;
-    s->remote_protoflags = remote;
-}
-
-static bool ssh1_connection_filter_queue(struct ssh1_connection_state *s)
-{
-    PktIn *pktin;
-    ptrlen data;
-    struct ssh1_channel *c;
-    unsigned localid;
-    bool expect_halfopen;
-
-    while (1) {
-        if (ssh1_common_filter_queue(&s->ppl))
-            return true;
-        if ((pktin = pq_peek(s->ppl.in_pq)) == NULL)
-            return false;
-
-        switch (pktin->type) {
-          case SSH1_MSG_CHANNEL_DATA:
-          case SSH1_MSG_CHANNEL_OPEN_CONFIRMATION:
-          case SSH1_MSG_CHANNEL_OPEN_FAILURE:
-          case SSH1_MSG_CHANNEL_CLOSE:
-          case SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION:
-            /*
-             * Common preliminary code for all the messages from the
-             * server that cite one of our channel ids: look up that
-             * channel id, check it exists, and if it's for a sharing
-             * downstream, pass it on.
-             */
-            localid = get_uint32(pktin);
-            c = find234(s->channels, &localid, ssh1_channelfind);
-
-            expect_halfopen = (
-                pktin->type == SSH1_MSG_CHANNEL_OPEN_CONFIRMATION ||
-                pktin->type == SSH1_MSG_CHANNEL_OPEN_FAILURE);
-
-            if (!c || c->halfopen != expect_halfopen) {
-                ssh_remote_error(
-                    s->ppl.ssh, "Received %s for %s channel %u",
-                    ssh1_pkt_type(pktin->type),
-                    !c ? "nonexistent" : c->halfopen ? "half-open" : "open",
-                    localid);
-                return true;
-            }
-
-            switch (pktin->type) {
-              case SSH1_MSG_CHANNEL_OPEN_CONFIRMATION:
-                assert(c->halfopen);
-                c->remoteid = get_uint32(pktin);
-                c->halfopen = false;
-                c->throttling_conn = false;
-
-                chan_open_confirmation(c->chan);
-
-                /*
-                 * Now that the channel is fully open, it's possible
-                 * in principle to immediately close it. Check whether
-                 * it wants us to!
-                 *
-                 * This can occur if a local socket error occurred
-                 * between us sending out CHANNEL_OPEN and receiving
-                 * OPEN_CONFIRMATION. If that happens, all we can do
-                 * is immediately initiate close proceedings now that
-                 * we know the server's id to put in the close
-                 * message. We'll have handled that in this code by
-                 * having already turned c->chan into a zombie, so its
-                 * want_close method (which ssh1_channel_check_close
-                 * will consult) will already be returning true.
-                 */
-                ssh1_channel_check_close(c);
-
-                if (c->pending_eof)
-                    ssh1_channel_try_eof(c); /* in case we had a pending EOF */
-                break;
-
-              case SSH1_MSG_CHANNEL_OPEN_FAILURE:
-                assert(c->halfopen);
-
-                chan_open_failed(c->chan, NULL);
-                chan_free(c->chan);
-
-                del234(s->channels, c);
-                ssh1_channel_free(c);
-                break;
-
-              case SSH1_MSG_CHANNEL_DATA:
-                data = get_string(pktin);
-                if (!get_err(pktin)) {
-                    int bufsize = chan_send(
-                        c->chan, false, data.ptr, data.len);
-
-                    if (!c->throttling_conn && bufsize > SSH1_BUFFER_LIMIT) {
-                        c->throttling_conn = true;
-                        ssh_throttle_conn(s->ppl.ssh, +1);
-                    }
-                }
-                break;
-
-              case SSH1_MSG_CHANNEL_CLOSE:
-                if (!(c->closes & CLOSES_RCVD_CLOSE)) {
-                    c->closes |= CLOSES_RCVD_CLOSE;
-                    chan_send_eof(c->chan);
-                    ssh1_channel_check_close(c);
-                }
-                break;
-
-              case SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION:
-                if (!(c->closes & CLOSES_RCVD_CLOSECONF)) {
-                    if (!(c->closes & CLOSES_SENT_CLOSE)) {
-                        ssh_remote_error(
-                            s->ppl.ssh,
-                            "Received CHANNEL_CLOSE_CONFIRMATION for channel"
-                            " %u for which we never sent CHANNEL_CLOSE\n",
-                            c->localid);
-                        return true;
-                    }
-
-                    c->closes |= CLOSES_RCVD_CLOSECONF;
-                    ssh1_channel_check_close(c);
-                }
-                break;
-            }
-
-            pq_pop(s->ppl.in_pq);
-            break;
-
-          default:
-            if (ssh1_handle_direction_specific_packet(s, pktin)) {
-                pq_pop(s->ppl.in_pq);
-                if (ssh1_check_termination(s))
-                    return true;
-            } else {
-                return false;
-            }
-        }
-    }
-}
-
-static PktIn *ssh1_connection_pop(struct ssh1_connection_state *s)
-{
-    ssh1_connection_filter_queue(s);
-    return pq_pop(s->ppl.in_pq);
-}
-
-static void ssh1_connection_process_queue(PacketProtocolLayer *ppl)
-{
-    struct ssh1_connection_state *s =
-        container_of(ppl, struct ssh1_connection_state, ppl);
-    PktIn *pktin;
-
-    if (ssh1_connection_filter_queue(s)) /* no matter why we were called */
-        return;
-
-    crBegin(s->crState);
-
-    /*
-     * Signal the seat that authentication is done, so that it can
-     * deploy spoofing defences. If it doesn't have any, deploy our
-     * own fallback one.
-     *
-     * We do this here rather than at the end of userauth, because we
-     * might not have gone through userauth at all (if we're a
-     * connection-sharing downstream).
-     */
-    if (ssh1_connection_need_antispoof_prompt(s)) {
-        s->antispoof_prompt = new_prompts();
-        s->antispoof_prompt->to_server = true;
-        s->antispoof_prompt->from_server = false;
-        s->antispoof_prompt->name = dupstr("Authentication successful");
-        add_prompt(
-            s->antispoof_prompt,
-            dupstr("Access granted. Press Return to begin session. "), false);
-        s->antispoof_ret = seat_get_userpass_input(
-            s->ppl.seat, s->antispoof_prompt, NULL);
-        while (1) {
-            while (s->antispoof_ret < 0 &&
-                   bufchain_size(s->ppl.user_input) > 0)
-                s->antispoof_ret = seat_get_userpass_input(
-                    s->ppl.seat, s->antispoof_prompt, s->ppl.user_input);
-
-            if (s->antispoof_ret >= 0)
-                break;
-
-            s->want_user_input = true;
-            crReturnV;
-            s->want_user_input = false;
-        }
-        free_prompts(s->antispoof_prompt);
-        s->antispoof_prompt = NULL;
-    }
-
-    portfwdmgr_config(s->portfwdmgr, s->conf);
-    s->portfwdmgr_configured = true;
-
-    while (!s->finished_setup) {
-        ssh1_connection_direction_specific_setup(s);
-        crReturnV;
-    }
-
-    while (1) {
-
-        /*
-         * By this point, most incoming packets are already being
-         * handled by filter_queue, and we need only pay attention to
-         * the unusual ones.
-         */
-
-        if ((pktin = ssh1_connection_pop(s)) != NULL) {
-            ssh_proto_error(s->ppl.ssh, "Unexpected packet received, "
-                            "type %d (%s)", pktin->type,
-                            ssh1_pkt_type(pktin->type));
-            return;
-        }
-        crReturnV;
-    }
-
-    crFinishV;
-}
-
-static void ssh1_channel_check_close(struct ssh1_channel *c)
-{
-    struct ssh1_connection_state *s = c->connlayer;
-    PktOut *pktout;
-
-    if (c->halfopen) {
-        /*
-         * If we've sent out our own CHANNEL_OPEN but not yet seen
-         * either OPEN_CONFIRMATION or OPEN_FAILURE in response, then
-         * it's too early to be sending close messages of any kind.
-         */
-        return;
-    }
-
-    if ((!((CLOSES_SENT_CLOSE | CLOSES_RCVD_CLOSE) & ~c->closes) ||
-         chan_want_close(c->chan, (c->closes & CLOSES_SENT_CLOSE),
-                         (c->closes & CLOSES_RCVD_CLOSE))) &&
-        !(c->closes & CLOSES_SENT_CLOSECONF)) {
-        /*
-         * We have both sent and received CLOSE (or the channel type
-         * doesn't need us to), which means the channel is in final
-         * wind-up. Send CLOSE and/or CLOSE_CONFIRMATION, whichever we
-         * haven't sent yet.
-         */
-        if (!(c->closes & CLOSES_SENT_CLOSE)) {
-            pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_CHANNEL_CLOSE);
-            put_uint32(pktout, c->remoteid);
-            pq_push(s->ppl.out_pq, pktout);
-            c->closes |= CLOSES_SENT_CLOSE;
-        }
-        if (c->closes & CLOSES_RCVD_CLOSE) {
-            pktout = ssh_bpp_new_pktout(
-                s->ppl.bpp, SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION);
-            put_uint32(pktout, c->remoteid);
-            pq_push(s->ppl.out_pq, pktout);
-            c->closes |= CLOSES_SENT_CLOSECONF;
-        }
-    }
-
-    if (!((CLOSES_SENT_CLOSECONF | CLOSES_RCVD_CLOSECONF) & ~c->closes)) {
-        /*
-         * We have both sent and received CLOSE_CONFIRMATION, which
-         * means we're completely done with the channel.
-         */
-        ssh1_channel_destroy(c);
-    }
-}
-
-static void ssh1_channel_try_eof(struct ssh1_channel *c)
-{
-    struct ssh1_connection_state *s = c->connlayer;
-    PktOut *pktout;
-    assert(c->pending_eof);          /* precondition for calling us */
-    if (c->halfopen)
-        return;                 /* can't close: not even opened yet */
-
-    c->pending_eof = false;            /* we're about to send it */
-
-    pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_CHANNEL_CLOSE);
-    put_uint32(pktout, c->remoteid);
-    pq_push(s->ppl.out_pq, pktout);
-    c->closes |= CLOSES_SENT_CLOSE;
-
-    ssh1_channel_check_close(c);
-}
-
-/*
- * Close any local socket and free any local resources associated with
- * a channel.  This converts the channel into a zombie.
- */
-static void ssh1_channel_close_local(struct ssh1_channel *c,
-                                     const char *reason)
-{
-    struct ssh1_connection_state *s = c->connlayer;
-    PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
-    char *msg = chan_log_close_msg(c->chan);
-
-    if (msg != NULL) {
-        ppl_logevent("%s%s%s", msg, reason ? " " : "", reason ? reason : "");
-        sfree(msg);
-    }
-
-    chan_free(c->chan);
-    c->chan = zombiechan_new();
-}
-
-static void ssh1_check_termination_callback(void *vctx)
-{
-    struct ssh1_connection_state *s = (struct ssh1_connection_state *)vctx;
-    ssh1_check_termination(s);
-}
-
-static void ssh1_channel_destroy(struct ssh1_channel *c)
-{
-    struct ssh1_connection_state *s = c->connlayer;
-
-    ssh1_channel_close_local(c, NULL);
-    del234(s->channels, c);
-    ssh1_channel_free(c);
-
-    /*
-     * If that was the last channel left open, we might need to
-     * terminate. But we'll be a bit cautious, by doing that in a
-     * toplevel callback, just in case anything on the current call
-     * stack objects to this entire PPL being freed.
-     */
-    queue_toplevel_callback(ssh1_check_termination_callback, s);
-}
-
-bool ssh1_check_termination(struct ssh1_connection_state *s)
-{
-    /*
-     * Decide whether we should terminate the SSH connection now.
-     * Called after a channel goes away, or when the main session
-     * returns SSH1_SMSG_EXIT_STATUS; we terminate when none of either
-     * is left.
-     */
-    if (s->session_terminated && count234(s->channels) == 0) {
-        PktOut *pktout = ssh_bpp_new_pktout(
-            s->ppl.bpp, SSH1_CMSG_EXIT_CONFIRMATION);
-        pq_push(s->ppl.out_pq, pktout);
-
-        ssh_user_close(s->ppl.ssh, "Session finished");
-        return true;
-    }
-
-    return false;
-}
-
-/*
- * Set up most of a new ssh1_channel. Leaves chan untouched (since it
- * will sometimes have been filled in before calling this).
- */
-void ssh1_channel_init(struct ssh1_channel *c)
-{
-    struct ssh1_connection_state *s = c->connlayer;
-    c->closes = 0;
-    c->pending_eof = false;
-    c->throttling_conn = false;
-    c->sc.vt = &ssh1channel_vtable;
-    c->sc.cl = &s->cl;
-    c->localid = alloc_channel_id(s->channels, struct ssh1_channel);
-    add234(s->channels, c);
-}
-
-static Conf *ssh1channel_get_conf(SshChannel *sc)
-{
-    struct ssh1_channel *c = container_of(sc, struct ssh1_channel, sc);
-    struct ssh1_connection_state *s = c->connlayer;
-    return s->conf;
-}
-
-static void ssh1channel_write_eof(SshChannel *sc)
-{
-    struct ssh1_channel *c = container_of(sc, struct ssh1_channel, sc);
-
-    if (c->closes & CLOSES_SENT_CLOSE)
-        return;
-
-    c->pending_eof = true;
-    ssh1_channel_try_eof(c);
-}
-
-static void ssh1channel_initiate_close(SshChannel *sc, const char *err)
-{
-    struct ssh1_channel *c = container_of(sc, struct ssh1_channel, sc);
-    char *reason;
-
-    reason = err ? dupprintf("due to local error: %s", err) : NULL;
-    ssh1_channel_close_local(c, reason);
-    sfree(reason);
-    c->pending_eof = false;   /* this will confuse a zombie channel */
-
-    ssh1_channel_check_close(c);
-}
-
-static void ssh1channel_unthrottle(SshChannel *sc, size_t bufsize)
-{
-    struct ssh1_channel *c = container_of(sc, struct ssh1_channel, sc);
-    struct ssh1_connection_state *s = c->connlayer;
-
-    if (c->throttling_conn && bufsize <= SSH1_BUFFER_LIMIT) {
-        c->throttling_conn = false;
-        ssh_throttle_conn(s->ppl.ssh, -1);
-    }
-}
-
-static size_t ssh1channel_write(
-    SshChannel *sc, bool is_stderr, const void *buf, size_t len)
-{
-    struct ssh1_channel *c = container_of(sc, struct ssh1_channel, sc);
-    struct ssh1_connection_state *s = c->connlayer;
-
-    pinitassert(!(c->closes & CLOSES_SENT_CLOSE));
-
-    PktOut *pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_CHANNEL_DATA);
-    put_uint32(pktout, c->remoteid);
-    put_string(pktout, buf, len);
-    pq_push(s->ppl.out_pq, pktout);
-
-    /*
-     * In SSH-1 we can return 0 here - implying that channels are
-     * never individually throttled - because the only circumstance
-     * that can cause throttling will be the whole SSH connection
-     * backing up, in which case _everything_ will be throttled as a
-     * whole.
-     */
-    return 0;
-}
-
-static struct X11FakeAuth *ssh1_add_x11_display(
-    ConnectionLayer *cl, int authtype, struct X11Display *disp)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-    struct X11FakeAuth *auth = x11_invent_fake_auth(s->x11authtree, authtype);
-    auth->disp = disp;
-    return auth;
-}
-
-static SshChannel *ssh1_lportfwd_open(
-    ConnectionLayer *cl, const char *hostname, int port,
-    const char *description, const SocketPeerInfo *pi, Channel *chan)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-    PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
-    struct ssh1_channel *c = snew(struct ssh1_channel);
-    PktOut *pktout;
-
-    c->connlayer = s;
-    ssh1_channel_init(c);
-    c->halfopen = true;
-    c->chan = chan;
-
-    ppl_logevent("Opening connection to %s:%d for %s",
-                 hostname, port, description);
-
-    pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_PORT_OPEN);
-    put_uint32(pktout, c->localid);
-    put_stringz(pktout, hostname);
-    put_uint32(pktout, port);
-    /* originator string would go here, but we didn't specify
-     * SSH_PROTOFLAG_HOST_IN_FWD_OPEN */
-    pq_push(s->ppl.out_pq, pktout);
-
-    return &c->sc;
-}
-
-static void ssh1_rportfwd_remove(ConnectionLayer *cl, struct ssh_rportfwd *rpf)
-{
-    /*
-     * We cannot cancel listening ports on the server side in SSH-1!
-     * There's no message to support it.
-     */
-}
-
-static bool ssh1_agent_forwarding_permitted(ConnectionLayer *cl)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-    return conf_get_bool(s->conf, CONF_agentfwd) && agent_exists();
-}
-
-static void ssh1_connection_special_cmd(PacketProtocolLayer *ppl,
-                                        SessionSpecialCode code, int arg)
-{
-    struct ssh1_connection_state *s =
-        container_of(ppl, struct ssh1_connection_state, ppl);
-    PktOut *pktout;
-
-    if (code == SS_PING || code == SS_NOP) {
-        if (!(s->ppl.remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE)) {
-            pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_IGNORE);
-            put_stringz(pktout, "");
-            pq_push(s->ppl.out_pq, pktout);
-        }
-    } else if (s->mainchan) {
-        mainchan_special_cmd(s->mainchan, code, arg);
-    }
-}
-
-static void ssh1_terminal_size(ConnectionLayer *cl, int width, int height)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-
-    s->term_width = width;
-    s->term_height = height;
-    if (s->mainchan)
-        mainchan_terminal_size(s->mainchan, width, height);
-}
-
-static void ssh1_stdout_unthrottle(ConnectionLayer *cl, size_t bufsize)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-
-    if (s->stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
-        s->stdout_throttling = false;
-        ssh_throttle_conn(s->ppl.ssh, -1);
-    }
-}
-
-static size_t ssh1_stdin_backlog(ConnectionLayer *cl)
-{
-    return 0;
-}
-
-static void ssh1_throttle_all_channels(ConnectionLayer *cl, bool throttled)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-    struct ssh1_channel *c;
-    int i;
-
-    for (i = 0; NULL != (c = index234(s->channels, i)); i++)
-        chan_set_input_wanted(c->chan, !throttled);
-}
-
-static bool ssh1_ldisc_option(ConnectionLayer *cl, int option)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-
-    return s->ldisc_opts[option];
-}
-
-static void ssh1_set_ldisc_option(ConnectionLayer *cl, int option, bool value)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-
-    s->ldisc_opts[option] = value;
-}
-
-static void ssh1_enable_x_fwd(ConnectionLayer *cl)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-
-    s->X11_fwd_enabled = true;
-}
-
-static void ssh1_set_wants_user_input(ConnectionLayer *cl, bool wanted)
-{
-    struct ssh1_connection_state *s =
-        container_of(cl, struct ssh1_connection_state, cl);
-
-    s->want_user_input = wanted;
-    s->finished_setup = true;
-}
-
-static bool ssh1_connection_want_user_input(PacketProtocolLayer *ppl)
-{
-    struct ssh1_connection_state *s =
-        container_of(ppl, struct ssh1_connection_state, ppl);
-
-    return s->want_user_input;
-}
-
-static void ssh1_connection_got_user_input(PacketProtocolLayer *ppl)
-{
-    struct ssh1_connection_state *s =
-        container_of(ppl, struct ssh1_connection_state, ppl);
-
-    while (s->mainchan && bufchain_size(s->ppl.user_input) > 0) {
-        /*
-         * Add user input to the main channel's buffer.
-         */
-        ptrlen data = bufchain_prefix(s->ppl.user_input);
-        if (data.len > 512)
-            data.len = 512;
-        sshfwd_write(&s->mainchan_sc, data.ptr, data.len);
-        bufchain_consume(s->ppl.user_input, data.len);
-    }
-}
-
-static void ssh1_connection_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
-{
-    struct ssh1_connection_state *s =
-        container_of(ppl, struct ssh1_connection_state, ppl);
-
-    conf_free(s->conf);
-    s->conf = conf_copy(conf);
-
-    if (s->portfwdmgr_configured)
-        portfwdmgr_config(s->portfwdmgr, s->conf);
-}
-
-#include <puttyexp.h>
-
-static unsigned int ssh1_connection_winscp_query(PacketProtocolLayer *ppl, int query)
-{
-    struct ssh1_connection_state *s =
-        container_of(ppl, struct ssh1_connection_state, ppl);
-
-    if (query == WINSCP_QUERY_TIMER)
-    {
-        return 0; // dummy
-    }
-    else if (query == WINSCP_QUERY_REMMAXPKT)
-    {
-        return 0; // dummy
-    }
-    else if (query == WINSCP_QUERY_MAIN_CHANNEL)
-    {
-        return s->finished_setup;
-    }
-    else
-    {
-        assert(0);
-        return 0;
-    }
-}

+ 0 - 123
source/putty/ssh1connection.h

@@ -1,123 +0,0 @@
-struct ssh1_channel;
-
-struct outstanding_succfail;
-
-struct ssh1_connection_state {
-    int crState;
-
-    Conf *conf;
-    int local_protoflags, remote_protoflags;
-
-    tree234 *channels;                 /* indexed by local id */
-
-    /* In SSH-1, the main session doesn't take the form of a 'channel'
-     * according to the wire protocol. But we want to use the same API
-     * for it, so we define an SshChannel here - but one that uses a
-     * separate vtable from the usual one, so it doesn't map to a
-     * struct ssh1_channel as all the others do. */
-    SshChannel mainchan_sc;
-    Channel *mainchan_chan;            /* the other end of mainchan_sc */
-    mainchan *mainchan;                /* and its subtype */
-
-    bool got_pty;
-    bool ldisc_opts[LD_N_OPTIONS];
-    bool stdout_throttling;
-    bool want_user_input;
-    bool session_terminated;
-    int term_width, term_height, term_width_orig, term_height_orig;
-
-    bool X11_fwd_enabled;
-    struct X11Display *x11disp;
-    struct X11FakeAuth *x11auth;
-    tree234 *x11authtree;
-
-    tree234 *rportfwds;
-    PortFwdManager *portfwdmgr;
-    bool portfwdmgr_configured;
-
-    bool finished_setup;
-
-    /*
-     * These store the list of requests that we're waiting for
-     * SSH_SMSG_{SUCCESS,FAILURE} replies to. (Those messages don't
-     * come with any indication of what they're in response to, so we
-     * have to keep track of the queue ourselves.)
-     */
-    struct outstanding_succfail *succfail_head, *succfail_tail;
-
-    bool compressing;                  /* used in server mode only */
-    bool sent_exit_status;             /* also for server mode */
-
-    prompts_t *antispoof_prompt;
-    int antispoof_ret;
-
-    const SshServerConfig *ssc;
-
-    ConnectionLayer cl;
-    PacketProtocolLayer ppl;
-};
-
-struct ssh1_channel {
-    struct ssh1_connection_state *connlayer;
-
-    unsigned remoteid, localid;
-    int type;
-    /* True if we opened this channel but server hasn't confirmed. */
-    bool halfopen;
-
-    /* Bitmap of whether we've sent/received CHANNEL_CLOSE and
-     * CHANNEL_CLOSE_CONFIRMATION. */
-#define CLOSES_SENT_CLOSE      1
-#define CLOSES_SENT_CLOSECONF  2
-#define CLOSES_RCVD_CLOSE      4
-#define CLOSES_RCVD_CLOSECONF  8
-    int closes;
-
-    /*
-     * This flag indicates that an EOF is pending on the outgoing side
-     * of the channel: that is, wherever we're getting the data for
-     * this channel has sent us some data followed by EOF. We can't
-     * actually send the EOF until we've finished sending the data, so
-     * we set this flag instead to remind us to do so once our buffer
-     * is clear.
-     */
-    bool pending_eof;
-
-    /*
-     * True if this channel is causing the underlying connection to be
-     * throttled.
-     */
-    bool throttling_conn;
-
-    /*
-     * True if we currently have backed-up data on the direction of
-     * this channel pointing out of the SSH connection, and therefore
-     * would prefer the 'Channel' implementation not to read further
-     * local input if possible.
-     */
-    bool throttled_by_backlog;
-
-    Channel *chan;      /* handle the client side of this channel, if not */
-    SshChannel sc;      /* entry point for chan to talk back to */
-};
-
-SshChannel *ssh1_session_open(ConnectionLayer *cl, Channel *chan);
-void ssh1_channel_init(struct ssh1_channel *c);
-void ssh1_channel_free(struct ssh1_channel *c);
-struct ssh_rportfwd *ssh1_rportfwd_alloc(
-    ConnectionLayer *cl,
-    const char *shost, int sport, const char *dhost, int dport,
-    int addressfamily, const char *log_description, PortFwdRecord *pfr,
-    ssh_sharing_connstate *share_ctx);
-SshChannel *ssh1_serverside_x11_open(
-    ConnectionLayer *cl, Channel *chan, const SocketPeerInfo *pi);
-SshChannel *ssh1_serverside_agent_open(ConnectionLayer *cl, Channel *chan);
-
-void ssh1_connection_direction_specific_setup(
-    struct ssh1_connection_state *s);
-bool ssh1_handle_direction_specific_packet(
-    struct ssh1_connection_state *s, PktIn *pktin);
-
-bool ssh1_check_termination(struct ssh1_connection_state *s);
-
-bool ssh1_connection_need_antispoof_prompt(struct ssh1_connection_state *s);

+ 0 - 1284
source/putty/ssh1login.c

@@ -1,1284 +0,0 @@
-/*
- * Packet protocol layer for the SSH-1 login phase (combining what
- * SSH-2 would think of as key exchange and user authentication).
- */
-
-#include <assert.h>
-
-#include "putty.h"
-#include "ssh.h"
-#include "mpint.h"
-#include "sshbpp.h"
-#include "sshppl.h"
-#include "sshcr.h"
-
-typedef struct agent_key {
-    RSAKey key;
-    strbuf *comment;
-    ptrlen blob; /* only used during initial parsing of agent response */
-} agent_key;
-
-struct ssh1_login_state {
-    int crState;
-
-    PacketProtocolLayer *successor_layer;
-
-    Conf *conf;
-
-    char *savedhost;
-    int savedport;
-    bool try_agent_auth;
-
-    int remote_protoflags;
-    int local_protoflags;
-    unsigned char session_key[32];
-    char *username;
-    agent_pending_query *auth_agent_query;
-
-    int len;
-    unsigned char *rsabuf;
-    unsigned long supported_ciphers_mask, supported_auths_mask;
-    bool tried_publickey, tried_agent;
-    bool tis_auth_refused, ccard_auth_refused;
-    unsigned char cookie[8];
-    unsigned char session_id[16];
-    int cipher_type;
-    strbuf *publickey_blob;
-    char *publickey_comment;
-    bool privatekey_available, privatekey_encrypted;
-    prompts_t *cur_prompt;
-    int userpass_ret;
-    char c;
-    int pwpkt_type;
-    void *agent_response_to_free;
-    ptrlen agent_response;
-    BinarySource asrc[1];          /* response from SSH agent */
-    size_t agent_keys_len;
-    agent_key *agent_keys;
-    size_t agent_key_index, agent_key_limit;
-    bool authed;
-    RSAKey key;
-    int dlgret;
-    Filename *keyfile;
-    RSAKey servkey, hostkey;
-    bool want_user_input;
-
-    StripCtrlChars *tis_scc;
-    bool tis_scc_initialised;
-
-    PacketProtocolLayer ppl;
-};
-
-static void ssh1_login_free(PacketProtocolLayer *);
-static void ssh1_login_process_queue(PacketProtocolLayer *);
-static void ssh1_login_dialog_callback(void *, int);
-static void ssh1_login_special_cmd(PacketProtocolLayer *ppl,
-                                   SessionSpecialCode code, int arg);
-static bool ssh1_login_want_user_input(PacketProtocolLayer *ppl);
-static void ssh1_login_got_user_input(PacketProtocolLayer *ppl);
-static void ssh1_login_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
-static unsigned int ssh1_login_winscp_query(PacketProtocolLayer *ppl, int query);
-
-static const PacketProtocolLayerVtable ssh1_login_vtable = {
-    // WINSCP
-    /*.free =*/ ssh1_login_free,
-    /*.process_queue =*/ ssh1_login_process_queue,
-    /*.get_specials =*/ ssh1_common_get_specials,
-    /*.special_cmd =*/ ssh1_login_special_cmd,
-    /*.want_user_input =*/ ssh1_login_want_user_input,
-    /*.got_user_input =*/ ssh1_login_got_user_input,
-    /*.reconfigure =*/ ssh1_login_reconfigure,
-    /*.queued_data_size =*/ ssh_ppl_default_queued_data_size,
-    /*.name =*/ NULL, /* no layer names in SSH-1 */
-    ssh1_login_winscp_query,
-};
-
-static void ssh1_login_agent_query(struct ssh1_login_state *s, strbuf *req);
-static void ssh1_login_agent_callback(void *loginv, void *reply, int replylen);
-
-PacketProtocolLayer *ssh1_login_new(
-    Conf *conf, const char *host, int port,
-    PacketProtocolLayer *successor_layer)
-{
-    struct ssh1_login_state *s = snew(struct ssh1_login_state);
-    memset(s, 0, sizeof(*s));
-    s->ppl.vt = &ssh1_login_vtable;
-
-    s->conf = conf_copy(conf);
-    s->savedhost = dupstr(host);
-    s->savedport = port;
-    s->successor_layer = successor_layer;
-    return &s->ppl;
-}
-
-static void ssh1_login_free(PacketProtocolLayer *ppl)
-{
-    struct ssh1_login_state *s =
-        container_of(ppl, struct ssh1_login_state, ppl);
-
-    if (s->successor_layer)
-        ssh_ppl_free(s->successor_layer);
-
-    conf_free(s->conf);
-    sfree(s->savedhost);
-    sfree(s->rsabuf);
-    sfree(s->username);
-    if (s->publickey_blob)
-        strbuf_free(s->publickey_blob);
-    sfree(s->publickey_comment);
-    if (s->cur_prompt)
-        free_prompts(s->cur_prompt);
-    if (s->agent_keys) {
-        size_t i; // WINSCP
-        for (i = 0; i < s->agent_keys_len; i++) {
-            freersakey(&s->agent_keys[i].key);
-            strbuf_free(s->agent_keys[i].comment);
-        }
-        sfree(s->agent_keys);
-    }
-    sfree(s->agent_response_to_free);
-    if (s->auth_agent_query)
-        agent_cancel_query(s->auth_agent_query);
-    sfree(s);
-}
-
-static bool ssh1_login_filter_queue(struct ssh1_login_state *s)
-{
-    return ssh1_common_filter_queue(&s->ppl);
-}
-
-static PktIn *ssh1_login_pop(struct ssh1_login_state *s)
-{
-    if (ssh1_login_filter_queue(s))
-        return NULL;
-    return pq_pop(s->ppl.in_pq);
-}
-
-static void ssh1_login_setup_tis_scc(struct ssh1_login_state *s);
-
-static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
-{
-    struct ssh1_login_state *s =
-        container_of(ppl, struct ssh1_login_state, ppl);
-    PktIn *pktin;
-    PktOut *pkt;
-    int i;
-
-    /* Filter centrally handled messages off the front of the queue on
-     * every entry to this coroutine, no matter where we're resuming
-     * from, even if we're _not_ looping on pq_pop. That way we can
-     * still proactively handle those messages even if we're waiting
-     * for a user response. */
-    if (ssh1_login_filter_queue(s))
-        return;
-
-    crBegin(s->crState);
-
-    crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
-
-    if (pktin->type != SSH1_SMSG_PUBLIC_KEY) {
-        ssh_proto_error(s->ppl.ssh, "Public key packet not received");
-        return;
-    }
-
-    ppl_logevent("Received public keys");
-
-    {
-        ptrlen pl = get_data(pktin, 8);
-        memcpy(s->cookie, pl.ptr, pl.len);
-    }
-
-    get_rsa_ssh1_pub(pktin, &s->servkey, RSA_SSH1_EXPONENT_FIRST);
-    get_rsa_ssh1_pub(pktin, &s->hostkey, RSA_SSH1_EXPONENT_FIRST);
-
-    s->hostkey.comment = NULL; /* avoid confusing rsa_ssh1_fingerprint */
-
-    /*
-     * Log the host key fingerprint.
-     */
-    if (!get_err(pktin)) {
-        char *fingerprint = rsa_ssh1_fingerprint(&s->hostkey);
-        ppl_logevent("Host key fingerprint is:");
-        ppl_logevent("      %s", fingerprint);
-        sfree(fingerprint);
-    }
-
-    s->remote_protoflags = get_uint32(pktin);
-    s->supported_ciphers_mask = get_uint32(pktin);
-    s->supported_auths_mask = get_uint32(pktin);
-
-    if (get_err(pktin)) {
-        ssh_proto_error(s->ppl.ssh, "Bad SSH-1 public key packet");
-        return;
-    }
-
-    if ((s->ppl.remote_bugs & BUG_CHOKES_ON_RSA))
-        s->supported_auths_mask &= ~(1 << SSH1_AUTH_RSA);
-
-    s->local_protoflags =
-        s->remote_protoflags & SSH1_PROTOFLAGS_SUPPORTED;
-    s->local_protoflags |= SSH1_PROTOFLAG_SCREEN_NUMBER;
-
-    ssh1_compute_session_id(s->session_id, s->cookie,
-                            &s->hostkey, &s->servkey);
-
-    random_read(s->session_key, 32);
-
-    /*
-     * Verify that the `bits' and `bytes' parameters match.
-     */
-    if (s->hostkey.bits > s->hostkey.bytes * 8 ||
-        s->servkey.bits > s->servkey.bytes * 8) {
-        ssh_proto_error(s->ppl.ssh, "SSH-1 public keys were badly formatted");
-        return;
-    }
-
-    s->len = 32;
-    if (s->len < s->hostkey.bytes)
-        s->len = s->hostkey.bytes;
-    if (s->len < s->servkey.bytes)
-        s->len = s->servkey.bytes;
-
-    s->rsabuf = snewn(s->len, unsigned char);
-
-    /*
-     * Verify the host key.
-     */
-    {
-        /*
-         * First format the key into a string.
-         */
-        char *keystr = rsastr_fmt(&s->hostkey);
-        char **fingerprints = rsa_ssh1_fake_all_fingerprints(&s->hostkey);
-
-        /* First check against manually configured host keys. */
-        s->dlgret = verify_ssh_manual_host_key(s->conf, fingerprints, NULL);
-        if (s->dlgret == 0) {          /* did not match */
-            ssh2_free_all_fingerprints(fingerprints);
-            sfree(keystr);
-            ssh_proto_error(s->ppl.ssh, "Host key did not appear in manually "
-                            "configured list");
-            return;
-        } else if (s->dlgret < 0) { /* none configured; use standard handling */
-            char *keydisp = ssh1_pubkey_str(&s->hostkey);
-            s->dlgret = seat_verify_ssh_host_key(
-                s->ppl.seat, s->savedhost, s->savedport, "rsa", keystr,
-                keydisp, fingerprints, ssh1_login_dialog_callback, s);
-            sfree(keydisp);
-            ssh2_free_all_fingerprints(fingerprints);
-            sfree(keystr);
-#ifdef FUZZING
-            s->dlgret = 1;
-#endif
-            crMaybeWaitUntilV(s->dlgret >= 0);
-
-            if (s->dlgret == 0) {
-                ssh_user_close(s->ppl.ssh,
-                               "User aborted at host key verification");
-                return;
-            }
-        } else {
-            ssh2_free_all_fingerprints(fingerprints);
-            sfree(keystr);
-        }
-    }
-
-    for (i = 0; i < 32; i++) {
-        s->rsabuf[i] = s->session_key[i];
-        if (i < 16)
-            s->rsabuf[i] ^= s->session_id[i];
-    }
-
-    {
-        RSAKey *smaller = (s->hostkey.bytes > s->servkey.bytes ?
-                           &s->servkey : &s->hostkey);
-        RSAKey *larger = (s->hostkey.bytes > s->servkey.bytes ?
-                          &s->hostkey : &s->servkey);
-
-        if (!rsa_ssh1_encrypt(s->rsabuf, 32, smaller) ||
-            !rsa_ssh1_encrypt(s->rsabuf, smaller->bytes, larger)) {
-            ssh_proto_error(s->ppl.ssh, "SSH-1 public key encryptions failed "
-                            "due to bad formatting");
-            return;
-        }
-    }
-
-    ppl_logevent("Encrypted session key");
-
-    {
-        bool cipher_chosen = false, warn = false;
-        const char *cipher_string = NULL;
-        int i;
-        for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
-            int next_cipher = conf_get_int_int(
-                s->conf, CONF_ssh_cipherlist, i);
-            if (next_cipher == CIPHER_WARN) {
-                /* If/when we choose a cipher, warn about it */
-                warn = true;
-            } else if (next_cipher == CIPHER_AES) {
-                /* XXX Probably don't need to mention this. */
-                ppl_logevent("AES not supported in SSH-1, skipping");
-            } else {
-                switch (next_cipher) {
-                  case CIPHER_3DES:     s->cipher_type = SSH1_CIPHER_3DES;
-                    cipher_string = "3DES"; break;
-                  case CIPHER_BLOWFISH: s->cipher_type = SSH1_CIPHER_BLOWFISH;
-                    cipher_string = "Blowfish"; break;
-                  case CIPHER_DES:      s->cipher_type = SSH1_CIPHER_DES;
-                    cipher_string = "single-DES"; break;
-                }
-                if (s->supported_ciphers_mask & (1 << s->cipher_type))
-                    cipher_chosen = true;
-            }
-        }
-        if (!cipher_chosen) {
-            if ((s->supported_ciphers_mask & (1 << SSH1_CIPHER_3DES)) == 0) {
-                ssh_proto_error(s->ppl.ssh, "Server violates SSH-1 protocol "
-                                "by not supporting 3DES encryption");
-            } else {
-                /* shouldn't happen */
-                ssh_sw_abort(s->ppl.ssh, "No supported ciphers found");
-            }
-            return;
-        }
-
-        /* Warn about chosen cipher if necessary. */
-        if (warn) {
-            s->dlgret = seat_confirm_weak_crypto_primitive(
-                s->ppl.seat, "cipher", cipher_string,
-                ssh1_login_dialog_callback, s);
-            crMaybeWaitUntilV(s->dlgret >= 0);
-            if (s->dlgret == 0) {
-                ssh_user_close(s->ppl.ssh, "User aborted at cipher warning");
-                return;
-            }
-        }
-    }
-
-    switch (s->cipher_type) {
-      case SSH1_CIPHER_3DES:
-        ppl_logevent("Using 3DES encryption");
-        break;
-      case SSH1_CIPHER_DES:
-        ppl_logevent("Using single-DES encryption");
-        break;
-      case SSH1_CIPHER_BLOWFISH:
-        ppl_logevent("Using Blowfish encryption");
-        break;
-    }
-
-    pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_SESSION_KEY);
-    put_byte(pkt, s->cipher_type);
-    put_data(pkt, s->cookie, 8);
-    put_uint16(pkt, s->len * 8);
-    put_data(pkt, s->rsabuf, s->len);
-    put_uint32(pkt, s->local_protoflags);
-    pq_push(s->ppl.out_pq, pkt);
-
-    ppl_logevent("Trying to enable encryption...");
-
-    sfree(s->rsabuf);
-    s->rsabuf = NULL;
-
-    /*
-     * Force the BPP to synchronously marshal all packets up to and
-     * including the SESSION_KEY into wire format, before we turn on
-     * crypto.
-     */
-    ssh_bpp_handle_output(s->ppl.bpp);
-
-    {
-        const ssh_cipheralg *cipher =
-            (s->cipher_type == SSH1_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
-             s->cipher_type == SSH1_CIPHER_DES ? &ssh_des : &ssh_3des_ssh1);
-        ssh1_bpp_new_cipher(s->ppl.bpp, cipher, s->session_key);
-    }
-
-    freersakey(&s->servkey);
-    freersakey(&s->hostkey);
-    crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
-
-    if (pktin->type != SSH1_SMSG_SUCCESS) {
-        ssh_proto_error(s->ppl.ssh, "Encryption not successfully enabled");
-        return;
-    }
-
-    ppl_logevent("Successfully started encryption");
-
-    if ((s->username = get_remote_username(s->conf)) == NULL) {
-        s->cur_prompt = new_prompts();
-        s->cur_prompt->to_server = true;
-        s->cur_prompt->from_server = false;
-        s->cur_prompt->name = dupstr("SSH login name");
-        add_prompt(s->cur_prompt, dupstr("login as: "), true);
-        s->userpass_ret = seat_get_userpass_input(
-            s->ppl.seat, s->cur_prompt, NULL);
-        while (1) {
-            while (s->userpass_ret < 0 &&
-                   bufchain_size(s->ppl.user_input) > 0)
-                s->userpass_ret = seat_get_userpass_input(
-                    s->ppl.seat, s->cur_prompt, s->ppl.user_input);
-
-            if (s->userpass_ret >= 0)
-                break;
-
-            s->want_user_input = true;
-            crReturnV;
-            s->want_user_input = false;
-        }
-        if (!s->userpass_ret) {
-            /*
-             * Failed to get a username. Terminate.
-             */
-            ssh_user_close(s->ppl.ssh, "No username provided");
-            return;
-        }
-        s->username = prompt_get_result(s->cur_prompt->prompts[0]);
-        free_prompts(s->cur_prompt);
-        s->cur_prompt = NULL;
-    }
-
-    pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_USER);
-    put_stringz(pkt, s->username);
-    pq_push(s->ppl.out_pq, pkt);
-
-    ppl_logevent(WINSCP_BOM "Sent username \"%s\"", s->username);
-    if (seat_verbose(s->ppl.seat) || seat_interactive(s->ppl.seat))
-        ppl_printf("Sent username \"%s\"\r\n", s->username);
-
-    crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
-
-    if (!(s->supported_auths_mask & (1 << SSH1_AUTH_RSA))) {
-        /* We must not attempt PK auth. Pretend we've already tried it. */
-        s->tried_publickey = s->tried_agent = true;
-    } else {
-        s->tried_publickey = s->tried_agent = false;
-    }
-    s->tis_auth_refused = s->ccard_auth_refused = false;
-
-    /*
-     * Load the public half of any configured keyfile for later use.
-     */
-    s->keyfile = conf_get_filename(s->conf, CONF_keyfile);
-    if (!filename_is_null(s->keyfile)) {
-        int keytype;
-        ppl_logevent(WINSCP_BOM "Reading key file \"%s\"", filename_to_str(s->keyfile));
-        keytype = key_type(s->keyfile);
-        if (keytype == SSH_KEYTYPE_SSH1 ||
-            keytype == SSH_KEYTYPE_SSH1_PUBLIC) {
-            const char *error;
-            s->publickey_blob = strbuf_new();
-            if (rsa1_loadpub_f(s->keyfile,
-                               BinarySink_UPCAST(s->publickey_blob),
-                               &s->publickey_comment, &error)) {
-                s->privatekey_available = (keytype == SSH_KEYTYPE_SSH1);
-                if (!s->privatekey_available)
-                    ppl_logevent("Key file contains public key only");
-                s->privatekey_encrypted = rsa1_encrypted_f(s->keyfile, NULL);
-            } else {
-                ppl_logevent("Unable to load key (%s)", error);
-                ppl_printf(WINSCP_BOM "Unable to load key file \"%s\" (%s)\r\n",
-                           filename_to_str(s->keyfile), error);
-
-                strbuf_free(s->publickey_blob);
-                s->publickey_blob = NULL;
-            }
-        } else {
-            ppl_logevent("Unable to use this key file (%s)",
-                         key_type_to_str(keytype));
-            ppl_printf(WINSCP_BOM "Unable to use key file \"%s\" (%s)\r\n",
-                       filename_to_str(s->keyfile),
-                       key_type_to_str(keytype));
-        }
-    }
-
-    /* Check whether we're configured to try Pageant, and also whether
-     * it's available. */
-    s->try_agent_auth = (conf_get_bool(s->conf, CONF_tryagent) &&
-                         agent_exists());
-
-    while (pktin->type == SSH1_SMSG_FAILURE) {
-        s->pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
-
-        if (s->try_agent_auth && !s->tried_agent) {
-            /*
-             * Attempt RSA authentication using Pageant.
-             */
-            s->authed = false;
-            s->tried_agent = true;
-            ppl_logevent("Pageant is running. Requesting keys.");
-
-            /* Request the keys held by the agent. */
-            {
-                strbuf *request = strbuf_new_for_agent_query();
-                put_byte(request, SSH1_AGENTC_REQUEST_RSA_IDENTITIES);
-                ssh1_login_agent_query(s, request);
-                strbuf_free(request);
-                crMaybeWaitUntilV(!s->auth_agent_query);
-            }
-            BinarySource_BARE_INIT_PL(s->asrc, s->agent_response);
-
-            get_uint32(s->asrc); /* skip length field */
-            if (get_byte(s->asrc) == SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
-                size_t nkeys = get_uint32(s->asrc);
-                size_t origpos = s->asrc->pos;
-
-                /*
-                 * Check that the agent response is well formed.
-                 */
-                { // WINSCP
-                size_t i; // WINSCP
-                for (i = 0; i < nkeys; i++) {
-                    get_rsa_ssh1_pub(s->asrc, NULL, RSA_SSH1_EXPONENT_FIRST);
-                    get_string(s->asrc); /* comment */
-                    if (get_err(s->asrc)) {
-                        ppl_logevent("Pageant's response was truncated");
-                        goto parsed_agent_query;
-                    }
-                }
-                } // WINSCP
-
-                /*
-                 * Copy the list of public-key blobs out of the Pageant
-                 * response.
-                 */
-                BinarySource_REWIND_TO(s->asrc, origpos);
-                s->agent_keys_len = nkeys;
-                s->agent_keys = snewn(s->agent_keys_len, agent_key);
-                { // WINSCP
-                size_t i; // WINSCP
-                for (i = 0; i < nkeys; i++) {
-                    memset(&s->agent_keys[i].key, 0,
-                           sizeof(s->agent_keys[i].key));
-
-                    { // WINSCP
-                    const char *blobstart = get_ptr(s->asrc);
-                    get_rsa_ssh1_pub(s->asrc, &s->agent_keys[i].key,
-                                     RSA_SSH1_EXPONENT_FIRST);
-                    { // WINSCP
-                    const char *blobend = get_ptr(s->asrc);
-
-                    s->agent_keys[i].comment = strbuf_new();
-                    put_datapl(s->agent_keys[i].comment, get_string(s->asrc));
-
-                    s->agent_keys[i].blob = make_ptrlen(
-                        blobstart, blobend - blobstart);
-                    } // WINSCP
-                    } // WINSCP
-                }
-                } // WINSCP
-
-                ppl_logevent("Pageant has %"SIZEu" SSH-1 keys", nkeys);
-
-                if (s->publickey_blob) {
-                    /*
-                     * If we've been given a specific public key blob,
-                     * filter the list of keys to try from the agent
-                     * down to only that one, or none if it's not
-                     * there.
-                     */
-                    ptrlen our_blob = ptrlen_from_strbuf(s->publickey_blob);
-                    size_t i;
-
-                    for (i = 0; i < nkeys; i++) {
-                        if (ptrlen_eq_ptrlen(our_blob, s->agent_keys[i].blob))
-                            break;
-                    }
-
-                    if (i < nkeys) {
-                        ppl_logevent("Pageant key #%"SIZEu" matches "
-                                     "configured key file", i);
-                        s->agent_key_index = i;
-                        s->agent_key_limit = i+1;
-                    } else {
-                        ppl_logevent("Configured key file not in Pageant");
-                        s->agent_key_index = 0;
-                        s->agent_key_limit = 0;
-                    }
-                } else {
-                    /*
-                     * Otherwise, try them all.
-                     */
-                    s->agent_key_index = 0;
-                    s->agent_key_limit = nkeys;
-                }
-            } else {
-                ppl_logevent("Failed to get reply from Pageant");
-            }
-          parsed_agent_query:;
-
-            for (; s->agent_key_index < s->agent_key_limit;
-                 s->agent_key_index++) {
-                ppl_logevent("Trying Pageant key #%"SIZEu, s->agent_key_index);
-                pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_RSA);
-                put_mp_ssh1(pkt,
-                            s->agent_keys[s->agent_key_index].key.modulus);
-                pq_push(s->ppl.out_pq, pkt);
-                crMaybeWaitUntilV((pktin = ssh1_login_pop(s))
-                                  != NULL);
-                if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
-                    ppl_logevent("Key refused");
-                    continue;
-                }
-                ppl_logevent("Received RSA challenge");
-
-                {
-                    mp_int *challenge = get_mp_ssh1(pktin);
-                    if (get_err(pktin)) {
-                        mp_free(challenge);
-                        ssh_proto_error(s->ppl.ssh, "Server's RSA challenge "
-                                        "was badly formatted");
-                        return;
-                    }
-
-                    { // WINSCP
-                    strbuf *agentreq = strbuf_new_for_agent_query();
-                    put_byte(agentreq, SSH1_AGENTC_RSA_CHALLENGE);
-
-                    rsa_ssh1_public_blob(
-                        BinarySink_UPCAST(agentreq),
-                        &s->agent_keys[s->agent_key_index].key,
-                        RSA_SSH1_EXPONENT_FIRST);
-
-                    put_mp_ssh1(agentreq, challenge);
-                    mp_free(challenge);
-
-                    put_data(agentreq, s->session_id, 16);
-                    put_uint32(agentreq, 1);    /* response format */
-                    ssh1_login_agent_query(s, agentreq);
-                    strbuf_free(agentreq);
-                    crMaybeWaitUntilV(!s->auth_agent_query);
-                    } // WINSCP
-                }
-
-                {
-                    const unsigned char *ret = s->agent_response.ptr;
-                    if (ret) {
-                        if (s->agent_response.len >= 5+16 &&
-                            ret[4] == SSH1_AGENT_RSA_RESPONSE) {
-                            ppl_logevent("Sending Pageant's response");
-                            pkt = ssh_bpp_new_pktout(
-                                s->ppl.bpp, SSH1_CMSG_AUTH_RSA_RESPONSE);
-                            put_data(pkt, ret + 5, 16);
-                            pq_push(s->ppl.out_pq, pkt);
-                            crMaybeWaitUntilV(
-                                (pktin = ssh1_login_pop(s))
-                                != NULL);
-                            if (pktin->type == SSH1_SMSG_SUCCESS) {
-                                ppl_logevent("Pageant's response "
-                                             "accepted");
-                                if (seat_verbose(s->ppl.seat)) {
-                                    ptrlen comment = ptrlen_from_strbuf(
-                                        s->agent_keys[s->agent_key_index].
-                                        comment);
-                                    ppl_printf("Authenticated using RSA "
-                                               "key \"%.*s\" from "
-                                               "agent\r\n",
-                                               PTRLEN_PRINTF(comment));
-                                }
-                                s->authed = true;
-                            } else
-                                ppl_logevent("Pageant's response not "
-                                             "accepted");
-                        } else {
-                            ppl_logevent("Pageant failed to answer "
-                                         "challenge");
-                            sfree((char *)ret);
-                        }
-                    } else {
-                        ppl_logevent("No reply received from Pageant");
-                    }
-                }
-                if (s->authed)
-                    break;
-            }
-            if (s->authed)
-                break;
-        }
-        if (s->publickey_blob && s->privatekey_available &&
-            !s->tried_publickey) {
-            /*
-             * Try public key authentication with the specified
-             * key file.
-             */
-            bool got_passphrase; /* need not be kept over crReturn */
-            if (seat_verbose(s->ppl.seat))
-                ppl_printf("Trying public key authentication.\r\n");
-            ppl_logevent(WINSCP_BOM "Trying public key \"%s\"",
-                         filename_to_str(s->keyfile));
-            s->tried_publickey = true;
-            got_passphrase = false;
-            while (!got_passphrase) {
-                /*
-                 * Get a passphrase, if necessary.
-                 */
-                int retd;
-                char *passphrase = NULL;    /* only written after crReturn */
-                const char *error;
-                if (!s->privatekey_encrypted) {
-                    if (seat_verbose(s->ppl.seat))
-                        ppl_printf("No passphrase required.\r\n");
-                    passphrase = NULL;
-                } else {
-                    s->cur_prompt = new_prompts();
-                    s->cur_prompt->to_server = false;
-                    s->cur_prompt->from_server = false;
-                    s->cur_prompt->name = dupstr("SSH key passphrase");
-                    add_prompt(s->cur_prompt,
-                               dupprintf("Passphrase for key \"%s\": ",
-                                         s->publickey_comment), false);
-                    s->userpass_ret = seat_get_userpass_input(
-                        s->ppl.seat, s->cur_prompt, NULL);
-                    while (1) {
-                        while (s->userpass_ret < 0 &&
-                               bufchain_size(s->ppl.user_input) > 0)
-                            s->userpass_ret = seat_get_userpass_input(
-                                s->ppl.seat, s->cur_prompt, s->ppl.user_input);
-
-                        if (s->userpass_ret >= 0)
-                            break;
-
-                        s->want_user_input = true;
-                        crReturnV;
-                        s->want_user_input = false;
-                    }
-                    if (!s->userpass_ret) {
-                        /* Failed to get a passphrase. Terminate. */
-                        ssh_user_close(s->ppl.ssh,
-                                       "User aborted at passphrase prompt");
-                        return;
-                    }
-                    passphrase = prompt_get_result(s->cur_prompt->prompts[0]);
-                    free_prompts(s->cur_prompt);
-                    s->cur_prompt = NULL;
-                }
-                /*
-                 * Try decrypting key with passphrase.
-                 */
-                retd = rsa1_load_f(s->keyfile, &s->key, passphrase, &error);
-                if (passphrase) {
-                    smemclr(passphrase, strlen(passphrase));
-                    sfree(passphrase);
-                }
-                if (retd == 1) {
-                    /* Correct passphrase. */
-                    got_passphrase = true;
-                } else if (retd == 0) {
-                    ppl_printf(WINSCP_BOM "Couldn't load private key from %s (%s).\r\n",
-                               filename_to_str(s->keyfile), error);
-                    got_passphrase = false;
-                    break;             /* go and try something else */
-                } else if (retd == -1) {
-                    ppl_printf("Wrong passphrase.\r\n");
-                    got_passphrase = false;
-                    /* and try again */
-                } else {
-                    unreachable("unexpected return from rsa1_load_f()");
-                }
-            }
-
-            if (got_passphrase) {
-
-                /*
-                 * Send a public key attempt.
-                 */
-                pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_RSA);
-                put_mp_ssh1(pkt, s->key.modulus);
-                pq_push(s->ppl.out_pq, pkt);
-
-                crMaybeWaitUntilV((pktin = ssh1_login_pop(s))
-                                  != NULL);
-                if (pktin->type == SSH1_SMSG_FAILURE) {
-                    ppl_printf("Server refused our public key.\r\n");
-                    continue;          /* go and try something else */
-                }
-                if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
-                    ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
-                                    " in response to offer of public key, "
-                                    "type %d (%s)", pktin->type,
-                                    ssh1_pkt_type(pktin->type));
-                    return;
-                }
-
-                {
-                    int i;
-                    unsigned char buffer[32];
-                    mp_int *challenge, *response;
-
-                    challenge = get_mp_ssh1(pktin);
-                    if (get_err(pktin)) {
-                        mp_free(challenge);
-                        ssh_proto_error(s->ppl.ssh, "Server's RSA challenge "
-                                        "was badly formatted");
-                        return;
-                    }
-                    response = rsa_ssh1_decrypt(challenge, &s->key);
-                    freersapriv(&s->key);   /* burn the evidence */
-
-                    for (i = 0; i < 32; i++) {
-                        buffer[i] = mp_get_byte(response, 31 - i);
-                    }
-
-                    {
-                        ssh_hash *h = ssh_hash_new(&ssh_md5);
-                        put_data(h, buffer, 32);
-                        put_data(h, s->session_id, 16);
-                        ssh_hash_final(h, buffer);
-                    }
-
-                    pkt = ssh_bpp_new_pktout(
-                        s->ppl.bpp, SSH1_CMSG_AUTH_RSA_RESPONSE);
-                    put_data(pkt, buffer, 16);
-                    pq_push(s->ppl.out_pq, pkt);
-
-                    mp_free(challenge);
-                    mp_free(response);
-                }
-
-                crMaybeWaitUntilV((pktin = ssh1_login_pop(s))
-                                  != NULL);
-                if (pktin->type == SSH1_SMSG_FAILURE) {
-                    if (seat_verbose(s->ppl.seat))
-                        ppl_printf("Failed to authenticate with"
-                                   " our public key.\r\n");
-                    continue;          /* go and try something else */
-                } else if (pktin->type != SSH1_SMSG_SUCCESS) {
-                    ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
-                                    " in response to RSA authentication, "
-                                    "type %d (%s)", pktin->type,
-                                    ssh1_pkt_type(pktin->type));
-                    return;
-                }
-
-                break;                 /* we're through! */
-            }
-
-        }
-
-        /*
-         * Otherwise, try various forms of password-like authentication.
-         */
-        s->cur_prompt = new_prompts();
-
-        if (conf_get_bool(s->conf, CONF_try_tis_auth) &&
-            (s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
-            !s->tis_auth_refused) {
-            ssh1_login_setup_tis_scc(s);
-            s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
-            ppl_logevent("Requested TIS authentication");
-            pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_TIS);
-            pq_push(s->ppl.out_pq, pkt);
-            crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
-            if (pktin->type == SSH1_SMSG_FAILURE) {
-                ppl_logevent("TIS authentication declined");
-                if (seat_interactive(s->ppl.seat))
-                    ppl_printf("TIS authentication refused.\r\n");
-                s->tis_auth_refused = true;
-                continue;
-            } else if (pktin->type == SSH1_SMSG_AUTH_TIS_CHALLENGE) {
-                ptrlen challenge = get_string(pktin);
-                if (get_err(pktin)) {
-                    ssh_proto_error(s->ppl.ssh, "TIS challenge packet was "
-                                    "badly formed");
-                    return;
-                }
-                ppl_logevent("Received TIS challenge");
-                s->cur_prompt->to_server = true;
-                s->cur_prompt->from_server = true;
-                s->cur_prompt->name = dupstr("SSH TIS authentication");
-
-                { // WINSCP
-                strbuf *sb = strbuf_new();
-                put_datapl(sb, PTRLEN_LITERAL("\
--- TIS authentication challenge from server: ---------------------------------\
-\r\n"));
-                if (s->tis_scc) {
-                    stripctrl_retarget(s->tis_scc, BinarySink_UPCAST(sb));
-                    put_datapl(s->tis_scc, challenge);
-                    stripctrl_retarget(s->tis_scc, NULL);
-                } else {
-                    put_datapl(sb, challenge);
-                }
-                if (!ptrlen_endswith(challenge, PTRLEN_LITERAL("\n"), NULL))
-                    put_datapl(sb, PTRLEN_LITERAL("\r\n"));
-                put_datapl(sb, PTRLEN_LITERAL("\
--- End of TIS authentication challenge from server: --------------------------\
-\r\n"));
-
-                s->cur_prompt->instruction = strbuf_to_str(sb);
-                s->cur_prompt->instr_reqd = true;
-                add_prompt(s->cur_prompt, dupstr(
-                               "TIS authentication response: "), false);
-                } // WINSCP
-            } else {
-                ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
-                                " in response to TIS authentication, "
-                                "type %d (%s)", pktin->type,
-                                ssh1_pkt_type(pktin->type));
-                return;
-            }
-        } else if (conf_get_bool(s->conf, CONF_try_tis_auth) &&
-            (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
-            !s->ccard_auth_refused) {
-            ssh1_login_setup_tis_scc(s);
-            s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
-            ppl_logevent("Requested CryptoCard authentication");
-            pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_CCARD);
-            pq_push(s->ppl.out_pq, pkt);
-            crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
-            if (pktin->type == SSH1_SMSG_FAILURE) {
-                ppl_logevent("CryptoCard authentication declined");
-                ppl_printf("CryptoCard authentication refused.\r\n");
-                s->ccard_auth_refused = true;
-                continue;
-            } else if (pktin->type == SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
-                ptrlen challenge = get_string(pktin);
-                if (get_err(pktin)) {
-                    ssh_proto_error(s->ppl.ssh, "CryptoCard challenge packet "
-                                    "was badly formed");
-                    return;
-                }
-                ppl_logevent("Received CryptoCard challenge");
-                s->cur_prompt->to_server = true;
-                s->cur_prompt->from_server = true;
-                s->cur_prompt->name = dupstr("SSH CryptoCard authentication");
-
-                { // WINSCP
-                strbuf *sb = strbuf_new();
-                put_datapl(sb, PTRLEN_LITERAL("\
--- CryptoCard authentication challenge from server: --------------------------\
-\r\n"));
-                if (s->tis_scc) {
-                    stripctrl_retarget(s->tis_scc, BinarySink_UPCAST(sb));
-                    put_datapl(s->tis_scc, challenge);
-                    stripctrl_retarget(s->tis_scc, NULL);
-                } else {
-                    put_datapl(sb, challenge);
-                }
-                if (!ptrlen_endswith(challenge, PTRLEN_LITERAL("\n"), NULL))
-                    put_datapl(sb, PTRLEN_LITERAL("\r\n"));
-                put_datapl(sb, PTRLEN_LITERAL("\
--- End of CryptoCard authentication challenge from server: -------------------\
-\r\n"));
-
-                s->cur_prompt->instruction = strbuf_to_str(sb);
-                s->cur_prompt->instr_reqd = true;
-                add_prompt(s->cur_prompt, dupstr(
-                               "CryptoCard authentication response: "), false);
-                } // WINSCP
-            } else {
-                ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
-                                " in response to TIS authentication, "
-                                "type %d (%s)", pktin->type,
-                                ssh1_pkt_type(pktin->type));
-                return;
-            }
-        }
-        if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
-            if ((s->supported_auths_mask & (1 << SSH1_AUTH_PASSWORD)) == 0) {
-                ssh_sw_abort(s->ppl.ssh, "No supported authentication methods "
-                             "available");
-                return;
-            }
-            s->cur_prompt->to_server = true;
-            s->cur_prompt->from_server = false;
-            s->cur_prompt->name = dupstr("SSH password");
-            add_prompt(s->cur_prompt, dupprintf("%s@%s's password: ",
-                                                s->username, s->savedhost),
-                       false);
-        }
-
-        /*
-         * Show password prompt, having first obtained it via a TIS
-         * or CryptoCard exchange if we're doing TIS or CryptoCard
-         * authentication.
-         */
-        s->userpass_ret = seat_get_userpass_input(
-            s->ppl.seat, s->cur_prompt, NULL);
-        while (1) {
-            while (s->userpass_ret < 0 &&
-                   bufchain_size(s->ppl.user_input) > 0)
-                s->userpass_ret = seat_get_userpass_input(
-                    s->ppl.seat, s->cur_prompt, s->ppl.user_input);
-
-            if (s->userpass_ret >= 0)
-                break;
-
-            s->want_user_input = true;
-            crReturnV;
-            s->want_user_input = false;
-        }
-        if (!s->userpass_ret) {
-            /*
-             * Failed to get a password (for example
-             * because one was supplied on the command line
-             * which has already failed to work). Terminate.
-             */
-            ssh_user_close(s->ppl.ssh, "User aborted at password prompt");
-            return;
-        }
-
-        if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
-            /*
-             * Defence against traffic analysis: we send a
-             * whole bunch of packets containing strings of
-             * different lengths. One of these strings is the
-             * password, in a SSH1_CMSG_AUTH_PASSWORD packet.
-             * The others are all random data in
-             * SSH1_MSG_IGNORE packets. This way a passive
-             * listener can't tell which is the password, and
-             * hence can't deduce the password length.
-             *
-             * Anybody with a password length greater than 16
-             * bytes is going to have enough entropy in their
-             * password that a listener won't find it _that_
-             * much help to know how long it is. So what we'll
-             * do is:
-             *
-             *  - if password length < 16, we send 15 packets
-             *    containing string lengths 1 through 15
-             *
-             *  - otherwise, we let N be the nearest multiple
-             *    of 8 below the password length, and send 8
-             *    packets containing string lengths N through
-             *    N+7. This won't obscure the order of
-             *    magnitude of the password length, but it will
-             *    introduce a bit of extra uncertainty.
-             *
-             * A few servers can't deal with SSH1_MSG_IGNORE, at
-             * least in this context. For these servers, we need
-             * an alternative defence. We make use of the fact
-             * that the password is interpreted as a C string:
-             * so we can append a NUL, then some random data.
-             *
-             * A few servers can deal with neither SSH1_MSG_IGNORE
-             * here _nor_ a padded password string.
-             * For these servers we are left with no defences
-             * against password length sniffing.
-             */
-            if (!(s->ppl.remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE) &&
-                !(s->ppl.remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
-                /*
-                 * The server can deal with SSH1_MSG_IGNORE, so
-                 * we can use the primary defence.
-                 */
-                int bottom, top, pwlen, i;
-                const char *pw = prompt_get_result_ref(
-                    s->cur_prompt->prompts[0]);
-
-                pwlen = strlen(pw);
-                if (pwlen < 16) {
-                    bottom = 0;    /* zero length passwords are OK! :-) */
-                    top = 15;
-                } else {
-                    bottom = pwlen & ~7;
-                    top = bottom + 7;
-                }
-
-                assert(pwlen >= bottom && pwlen <= top);
-
-                for (i = bottom; i <= top; i++) {
-                    if (i == pwlen) {
-                        pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
-                        put_stringz(pkt, pw);
-                        pq_push(s->ppl.out_pq, pkt);
-                    } else {
-                        strbuf *random_data = strbuf_new_nm();
-                        random_read(strbuf_append(random_data, i), i);
-
-                        pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_IGNORE);
-                        put_stringsb(pkt, random_data);
-                        pq_push(s->ppl.out_pq, pkt);
-                    }
-                }
-                ppl_logevent("Sending password with camouflage packets");
-            }
-            else if (!(s->ppl.remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
-                /*
-                 * The server can't deal with SSH1_MSG_IGNORE
-                 * but can deal with padded passwords, so we
-                 * can use the secondary defence.
-                 */
-                strbuf *padded_pw = strbuf_new_nm();
-
-                ppl_logevent("Sending length-padded password");
-                pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
-                put_asciz(padded_pw, prompt_get_result_ref(
-                              s->cur_prompt->prompts[0]));
-                { // WINSCP
-                size_t pad = 63 & -(ssize_t)padded_pw->len; // WINSCP
-                random_read(strbuf_append(padded_pw, pad), pad);
-                put_stringsb(pkt, padded_pw);
-                pq_push(s->ppl.out_pq, pkt);
-                } // WINSCP
-            } else {
-                /*
-                 * The server is believed unable to cope with
-                 * any of our password camouflage methods.
-                 */
-                ppl_logevent("Sending unpadded password");
-                pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
-                put_stringz(pkt, prompt_get_result_ref(
-                                s->cur_prompt->prompts[0]));
-                pq_push(s->ppl.out_pq, pkt);
-            }
-        } else {
-            pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
-            put_stringz(pkt, prompt_get_result_ref(s->cur_prompt->prompts[0]));
-            pq_push(s->ppl.out_pq, pkt);
-        }
-        ppl_logevent("Sent password");
-        free_prompts(s->cur_prompt);
-        s->cur_prompt = NULL;
-        crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
-        if (pktin->type == SSH1_SMSG_FAILURE) {
-            if (seat_verbose(s->ppl.seat))
-                ppl_printf("Access denied\r\n");
-            ppl_logevent("Authentication refused");
-        } else if (pktin->type != SSH1_SMSG_SUCCESS) {
-            ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
-                            " in response to password authentication, type %d "
-                            "(%s)", pktin->type, ssh1_pkt_type(pktin->type));
-            return;
-        }
-    }
-
-    ppl_logevent("Authentication successful");
-
-    if (conf_get_bool(s->conf, CONF_compression)) {
-        ppl_logevent("Requesting compression");
-        pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_REQUEST_COMPRESSION);
-        put_uint32(pkt, 6);         /* gzip compression level */
-        pq_push(s->ppl.out_pq, pkt);
-        crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
-        if (pktin->type == SSH1_SMSG_SUCCESS) {
-            /*
-             * We don't have to actually do anything here: the SSH-1
-             * BPP will take care of automatically starting the
-             * compression, by recognising our outgoing request packet
-             * and the success response. (Horrible, but it's the
-             * easiest way to avoid race conditions if other packets
-             * cross in transit.)
-             */
-        } else if (pktin->type == SSH1_SMSG_FAILURE) {
-            ppl_logevent("Server refused to enable compression");
-            ppl_printf("Server refused to compress\r\n");
-        } else {
-            ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
-                            " in response to compression request, type %d "
-                            "(%s)", pktin->type, ssh1_pkt_type(pktin->type));
-            return;
-        }
-    }
-
-    ssh1_connection_set_protoflags(
-        s->successor_layer, s->local_protoflags, s->remote_protoflags);
-    {
-        PacketProtocolLayer *successor = s->successor_layer;
-        s->successor_layer = NULL;     /* avoid freeing it ourself */
-        ssh_ppl_replace(&s->ppl, successor);
-        return;   /* we've just freed s, so avoid even touching s->crState */
-    }
-
-    crFinishV;
-}
-
-static void ssh1_login_setup_tis_scc(struct ssh1_login_state *s)
-{
-    if (s->tis_scc_initialised)
-        return;
-    s->tis_scc = seat_stripctrl_new(s->ppl.seat, NULL, SIC_KI_PROMPTS);
-    if (s->tis_scc)
-        stripctrl_enable_line_limiting(s->tis_scc);
-    s->tis_scc_initialised = true;
-}
-
-static void ssh1_login_dialog_callback(void *loginv, int ret)
-{
-    struct ssh1_login_state *s = (struct ssh1_login_state *)loginv;
-    s->dlgret = ret;
-    ssh_ppl_process_queue(&s->ppl);
-}
-
-static void ssh1_login_agent_query(struct ssh1_login_state *s, strbuf *req)
-{
-    void *response;
-    int response_len;
-
-    sfree(s->agent_response_to_free);
-    s->agent_response_to_free = NULL;
-
-    s->auth_agent_query = agent_query(req, &response, &response_len,
-                                      ssh1_login_agent_callback, s);
-    if (!s->auth_agent_query)
-        ssh1_login_agent_callback(s, response, response_len);
-}
-
-static void ssh1_login_agent_callback(void *loginv, void *reply, int replylen)
-{
-    struct ssh1_login_state *s = (struct ssh1_login_state *)loginv;
-
-    s->auth_agent_query = NULL;
-    s->agent_response_to_free = reply;
-    s->agent_response = make_ptrlen(reply, replylen);
-
-    queue_idempotent_callback(&s->ppl.ic_process_queue);
-}
-
-static void ssh1_login_special_cmd(PacketProtocolLayer *ppl,
-                                   SessionSpecialCode code, int arg)
-{
-    struct ssh1_login_state *s =
-        container_of(ppl, struct ssh1_login_state, ppl);
-    PktOut *pktout;
-
-    if (code == SS_PING || code == SS_NOP) {
-        if (!(s->ppl.remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE)) {
-            pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_IGNORE);
-            put_stringz(pktout, "");
-            pq_push(s->ppl.out_pq, pktout);
-        }
-    }
-}
-
-static bool ssh1_login_want_user_input(PacketProtocolLayer *ppl)
-{
-    struct ssh1_login_state *s =
-        container_of(ppl, struct ssh1_login_state, ppl);
-    return s->want_user_input;
-}
-
-static void ssh1_login_got_user_input(PacketProtocolLayer *ppl)
-{
-    struct ssh1_login_state *s =
-        container_of(ppl, struct ssh1_login_state, ppl);
-    if (s->want_user_input)
-        queue_idempotent_callback(&s->ppl.ic_process_queue);
-}
-
-static void ssh1_login_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
-{
-    struct ssh1_login_state *s =
-        container_of(ppl, struct ssh1_login_state, ppl);
-    ssh_ppl_reconfigure(s->successor_layer, conf);
-}
-
-#include <puttyexp.h>
-
-static unsigned int ssh1_login_winscp_query(PacketProtocolLayer *ppl, int query)
-{
-    struct ssh1_login_state *s =
-        container_of(ppl, struct ssh1_login_state, ppl);
-    if (query == WINSCP_QUERY_TIMER)
-    {
-        return 0;
-    }
-    else if (s->successor_layer->vt->winscp_query != NULL)
-    {
-        return ssh_ppl_winscp_query(s->successor_layer, query);
-    }
-    else
-    {
-        return 0;
-    }
-}

+ 0 - 1
source/putty/sshbpp.h

@@ -177,7 +177,6 @@ const char *ssh_verstring_get_local(BinaryPacketProtocol *);
 int ssh_verstring_get_bugs(BinaryPacketProtocol *);
 
 #ifdef MPEXT
-const ssh_cipher * ssh1_bpp_get_cipher(BinaryPacketProtocol *bpp);
 const ssh_cipher * ssh2_bpp_get_cscipher(BinaryPacketProtocol *bpp);
 const ssh_cipher * ssh2_bpp_get_sccipher(BinaryPacketProtocol *bpp);
 const struct ssh_compressor * ssh2_bpp_get_cscomp(BinaryPacketProtocol *bpp);

+ 0 - 109
source/putty/sshcrc.c

@@ -1,109 +0,0 @@
-/*
- * CRC32 implementation, as used in SSH-1.
- *
- * This particular form of the CRC uses the polynomial
- * P(x) = x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+1
- * and represents polynomials in bit-reversed form, so that the x^0
- * coefficient (constant term) appears in the bit with place value
- * 2^31, and the x^31 coefficient in the bit with place value 2^0. In
- * this representation, (x^32 mod P) = 0xEDB88320, so multiplying the
- * current state by x is done by shifting right by one bit, and XORing
- * that constant into the result if the bit shifted out was 1.
- *
- * There's a bewildering array of subtly different variants of CRC out
- * there, using different polynomials, both bit orders, and varying
- * the start and end conditions. There are catalogue websites such as
- * http://reveng.sourceforge.net/crc-catalogue/ , which generally seem
- * to have the convention of indexing CRCs by their 'check value',
- * defined as whatever you get if you hash the 9-byte test string
- * "123456789".
- *
- * The crc32_rfc1662() function below, which starts off the CRC state
- * at 0xFFFFFFFF and complements it after feeding all the data, gives
- * the check value 0xCBF43926, and matches the hash function that the
- * above catalogue refers to as "CRC-32/ISO-HDLC"; among other things,
- * it's also the "FCS-32" checksum described in RFC 1662 section C.3
- * (hence the name I've given it here).
- *
- * The crc32_ssh1() function implements the variant form used by
- * SSH-1, which uses the same update function, but starts the state at
- * zero and doesn't complement it at the end of the computation. The
- * check value for that version is 0x2DFD2D88, which that CRC
- * catalogue doesn't list at all.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "ssh.h"
-
-/*
- * Multiply a CRC value by x^4. This implementation strategy avoids
- * using a lookup table (which would be a side-channel hazard, since
- * SSH-1 applies this CRC to decrypted session data).
- *
- * The basic idea is that you'd like to "multiply" the shifted-out 4
- * bits by the CRC polynomial value 0xEDB88320, or rather by that
- * value shifted right 3 bits (since you want the _last_ bit shifted
- * out, i.e. the one originally at the 2^3 position, to generate
- * 0xEDB88320 itself). But the scare-quoted "multiply" would have to
- * be a multiplication of polynomials over GF(2), which differs from
- * integer multiplication in that you don't have any carries. In other
- * words, you make a copy of one input shifted left by the index of
- * each set bit in the other, so that adding them all together would
- * give you the ordinary integer product, and then you XOR them
- * together instead.
- *
- * With a 4-bit multiplier, the two kinds of multiplication coincide
- * provided the multiplicand has no two set bits at positions
- * differing by less than 4, because then no two copies of the
- * multiplier can overlap to generate a carry. So I break up the
- * intended multiplicand K = 0xEDB88320 >> 3 into three sub-constants
- * a,b,c with that property, such that a^b^c = K. Then I can multiply
- * m by each of them separately, and XOR together the results.
- */
-static inline uint32_t crc32_shift_4(uint32_t v)
-{
-    const uint32_t a = 0x11111044, b = 0x08840020, c = 0x04220000;
-    uint32_t m = v & 0xF;
-    return (v >> 4) ^ (a*m) ^ (b*m) ^ (c*m);
-}
-
-/*
- * The 8-bit shift you need every time you absorb an input byte,
- * implemented simply by iterating the 4-bit shift twice.
- */
-static inline uint32_t crc32_shift_8(uint32_t v)
-{
-    return crc32_shift_4(crc32_shift_4(v));
-}
-
-/*
- * Update an existing hash value with extra bytes of data.
- */
-uint32_t crc32_update(uint32_t crc, ptrlen data)
-{
-    const uint8_t *p = (const uint8_t *)data.ptr;
-    size_t len; // WINSCP
-    for (len = data.len; len-- > 0 ;)
-        crc = crc32_shift_8(crc ^ *p++);
-    return crc;
-}
-
-/*
- * The SSH-1 variant of CRC-32.
- */
-uint32_t crc32_ssh1(ptrlen data)
-{
-    return crc32_update(0, data);
-}
-
-/*
- * The official version of CRC-32. Nothing in PuTTY proper uses this,
- * but it's useful to expose it to testcrypt so that we can implement
- * standard test vectors.
- */
-uint32_t crc32_rfc1662(ptrlen data)
-{
-    return crc32_update(0xFFFFFFFF, data) ^ 0xFFFFFFFF;
-}

+ 0 - 171
source/putty/sshcrcda.c

@@ -1,171 +0,0 @@
-/*      $OpenBSD: deattack.c,v 1.14 2001/06/23 15:12:18 itojun Exp $    */
-
-/*
- * Cryptographic attack detector for ssh - source code
- *
- * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.
- *
- * All rights reserved. Redistribution and use in source and binary
- * forms, with or without modification, are permitted provided that
- * this copyright notice is retained.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
- * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS
- * SOFTWARE.
- *
- * Ariel Futoransky <[email protected]>
- * <http://www.core-sdi.com>
- *
- * Modified for use in PuTTY by Simon Tatham
- */
-
-#include <assert.h>
-#include "misc.h"
-#include "ssh.h"
-
-/* SSH Constants */
-#define SSH_MAXBLOCKS   (32 * 1024)
-#define SSH_BLOCKSIZE   (8)
-
-/* Hashing constants */
-#define HASH_MINSIZE    (8 * 1024)
-#define HASH_ENTRYSIZE  (sizeof(uint16_t))
-#define HASH_FACTOR(x)  ((x)*3/2)
-#define HASH_UNUSEDCHAR (0xff)
-#define HASH_UNUSED     (0xffff)
-#define HASH_IV         (0xfffe)
-
-#define HASH_MINBLOCKS  (7*SSH_BLOCKSIZE)
-
-/* Hash function (Input keys are cipher results) */
-#define HASH(x)         GET_32BIT_MSB_FIRST(x)
-
-#define CMP(a, b)       (memcmp(a, b, SSH_BLOCKSIZE))
-
-static const uint8_t ONE[4] = { 1, 0, 0, 0 };
-static const uint8_t ZERO[4] = { 0, 0, 0, 0 };
-
-struct crcda_ctx {
-    uint16_t *h;
-    uint32_t n;
-};
-
-struct crcda_ctx *crcda_make_context(void)
-{
-    struct crcda_ctx *ret = snew(struct crcda_ctx);
-    ret->h = NULL;
-    ret->n = HASH_MINSIZE / HASH_ENTRYSIZE;
-    return ret;
-}
-
-void crcda_free_context(struct crcda_ctx *ctx)
-{
-    if (ctx) {
-        sfree(ctx->h);
-        ctx->h = NULL;
-        sfree(ctx);
-    }
-}
-
-static void crc_update(uint32_t *a, const void *b)
-{
-    *a = crc32_update(*a, make_ptrlen(b, 4));
-}
-
-/* detect if a block is used in a particular pattern */
-static bool check_crc(const uint8_t *S, const uint8_t *buf,
-                      uint32_t len, const uint8_t *IV)
-{
-    uint32_t crc;
-    const uint8_t *c;
-
-    crc = 0;
-    if (IV && !CMP(S, IV)) {
-        crc_update(&crc, ONE);
-        crc_update(&crc, ZERO);
-    }
-    for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
-        if (!CMP(S, c)) {
-            crc_update(&crc, ONE);
-            crc_update(&crc, ZERO);
-        } else {
-            crc_update(&crc, ZERO);
-            crc_update(&crc, ZERO);
-        }
-    }
-    return (crc == 0);
-}
-
-/* Detect a crc32 compensation attack on a packet */
-bool detect_attack(struct crcda_ctx *ctx,
-                   const unsigned char *buf, uint32_t len,
-                   const unsigned char *IV)
-{
-    register uint32_t i, j;
-    uint32_t l;
-    register const uint8_t *c;
-    const uint8_t *d;
-
-    assert(!(len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||
-             len % SSH_BLOCKSIZE != 0));
-    for (l = ctx->n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)
-        ;
-
-    if (ctx->h == NULL) {
-        ctx->n = l;
-        ctx->h = snewn(ctx->n, uint16_t);
-    } else {
-        if (l > ctx->n) {
-            ctx->n = l;
-            ctx->h = sresize(ctx->h, ctx->n, uint16_t);
-        }
-    }
-
-    if (len <= HASH_MINBLOCKS) {
-        for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
-            if (IV && (!CMP(c, IV))) {
-                if ((check_crc(c, buf, len, IV)))
-                    return true;          /* attack detected */
-                else
-                    break;
-            }
-            for (d = buf; d < c; d += SSH_BLOCKSIZE) {
-                if (!CMP(c, d)) {
-                    if ((check_crc(c, buf, len, IV)))
-                        return true;      /* attack detected */
-                    else
-                        break;
-                }
-            }
-        }
-        return false;                  /* ok */
-    }
-    memset(ctx->h, HASH_UNUSEDCHAR, ctx->n * HASH_ENTRYSIZE);
-
-    if (IV)
-        ctx->h[HASH(IV) & (ctx->n - 1)] = HASH_IV;
-
-    for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
-        for (i = HASH(c) & (ctx->n - 1); ctx->h[i] != HASH_UNUSED;
-             i = (i + 1) & (ctx->n - 1)) {
-            if (ctx->h[i] == HASH_IV) {
-                assert(IV); /* or we wouldn't have stored HASH_IV above */
-                if (!CMP(c, IV)) {
-                    if (check_crc(c, buf, len, IV))
-                        return true;      /* attack detected */
-                    else
-                        break;
-                }
-            } else if (!CMP(c, buf + ctx->h[i] * SSH_BLOCKSIZE)) {
-                if (check_crc(c, buf, len, IV))
-                    return true;          /* attack detected */
-                else
-                    break;
-            }
-        }
-        ctx->h[i] = j;
-    }
-    return false;                          /* ok */
-}

+ 1 - 1
source/resource/TextsCore.h

@@ -170,7 +170,7 @@
 #define SFTP_STATUS_FILE_CORRUPT 242
 #define KEY_TYPE_UNKNOWN2       243
 #define KEY_TYPE_UNSUPPORTED2   244
-#define KEY_TYPE_DIFFERENT_SSH  245
+#define KEY_TYPE_SSH1           245
 #define SFTP_OVERWRITE_FILE_ERROR2 246
 #define SFTP_OVERWRITE_DELETE_BUTTON 247
 #define SPACE_AVAILABLE_ERROR   248

+ 1 - 1
source/resource/TextsCore1.rc

@@ -139,7 +139,7 @@ BEGIN
   SFTP_STATUS_FILE_CORRUPT, "The file is corrupt; an filesystem integrity check should be run."
   KEY_TYPE_UNKNOWN2, "File '%s' does not contain private key in known format."
   KEY_TYPE_UNSUPPORTED2, "**Private key file '%s' contains key in %s format. WinSCP supports only PuTTY format.**"
-  KEY_TYPE_DIFFERENT_SSH, "Private key file '%s' contains key in %s format. It does not follow your preferred SSH protocol version."
+  KEY_TYPE_SSH1, "Private key file '%s' contains key in deprecated SSH-1 format."
   SFTP_OVERWRITE_FILE_ERROR2, "Cannot overwrite remote file '%s'.$$\n \nPress 'Delete' to delete the file and create new one instead of overwriting it.$$"
   SFTP_OVERWRITE_DELETE_BUTTON, "&Delete"
   SPACE_AVAILABLE_ERROR, "Error checking space available for path '%s'."

+ 1 - 2
source/windows/GUITools.cpp

@@ -229,8 +229,7 @@ void __fastcall OpenSessionInPutty(const UnicodeString PuttyPath,
           {
             AddToList(PuttyParams, L"-C", L" ");
           }
-          AddToList(PuttyParams,
-            ((SessionData->SshProt == ssh1only || SessionData->SshProt == ssh1deprecated) ? L"-1" : L"-2"), L" ");
+          AddToList(PuttyParams, L"-2", L" ");
           if (!SessionData->LogicalHostName.IsEmpty())
           {
             AddToList(PuttyParams, FORMAT(L"-loghost \"%s\"", (SessionData->LogicalHostName)), L" ");

+ 1 - 1
source/windows/TerminalManager.cpp

@@ -1816,7 +1816,7 @@ bool __fastcall TTerminalManager::UploadPublicKey(
     const UnicodeString AuthorizedKeysFile = L"authorized_keys";
     UnicodeString AuthorizedKeysFilePath = FORMAT(L"%s/%s", (SshFolder, AuthorizedKeysFile));
 
-    VerifyAndConvertKey(FileName, ssh2only, false);
+    VerifyAndConvertKey(FileName, false);
 
     UnicodeString Comment;
     UnicodeString Line = GetPublicKeyLine(FileName, Comment);

+ 7 - 14
source/windows/Tools.cpp

@@ -1281,8 +1281,7 @@ static void __fastcall ConvertKey(UnicodeString & FileName, TKeyType Type)
   }
 }
 //---------------------------------------------------------------------------
-static void __fastcall DoVerifyKey(
-  UnicodeString & FileName, TSshProt SshProt, bool Convert, bool CanIgnore)
+static void __fastcall DoVerifyKey(UnicodeString & FileName, bool Convert, bool CanIgnore)
 {
   if (!FileName.Trim().IsEmpty())
   {
@@ -1326,14 +1325,7 @@ static void __fastcall DoVerifyKey(
         break;
 
       case ktSSH1:
-      case ktSSH2:
-        if ((Type == ktSSH1) != (SshProt == ssh1only))
-        {
-          Message =
-            MainInstructions(
-              FMTLOAD(KEY_TYPE_DIFFERENT_SSH,
-                (FileName, (Type == ktSSH1 ? L"SSH-1" : L"PuTTY SSH-2"))));
-        }
+        Message = MainInstructions(LoadStr(KEY_TYPE_SSH1));
         break;
 
       case ktSSH1Public:
@@ -1371,14 +1363,15 @@ static void __fastcall DoVerifyKey(
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall VerifyAndConvertKey(UnicodeString & FileName, TSshProt SshProt, bool CanIgnore)
+void __fastcall VerifyAndConvertKey(UnicodeString & FileName, bool CanIgnore)
 {
-  DoVerifyKey(FileName, SshProt, true, CanIgnore);
+  DoVerifyKey(FileName, true, CanIgnore);
 }
 //---------------------------------------------------------------------------
-void __fastcall VerifyKey(UnicodeString FileName, TSshProt SshProt)
+void __fastcall VerifyKey(const UnicodeString & FileName)
 {
-  DoVerifyKey(FileName, SshProt, false, true);
+  UnicodeString AFileName(FileName);
+  DoVerifyKey(AFileName, false, true);
 }
 //---------------------------------------------------------------------------
 void __fastcall VerifyCertificate(const UnicodeString & FileName)

+ 2 - 2
source/windows/Tools.h

@@ -70,8 +70,8 @@ void __fastcall CopyToClipboard(TStrings * Strings);
 void __fastcall ShutDownWindows();
 void __fastcall SuspendWindows();
 void __fastcall EditSelectBaseName(HWND Edit);
-void __fastcall VerifyAndConvertKey(UnicodeString & FileName, TSshProt SshProt, bool CanIgnore);
-void __fastcall VerifyKey(UnicodeString FileName, TSshProt SshProt);
+void __fastcall VerifyAndConvertKey(UnicodeString & FileName, bool CanIgnore);
+void __fastcall VerifyKey(const UnicodeString & FileName);
 void __fastcall VerifyCertificate(const UnicodeString & FileName);
 TStrings * __fastcall GetUnwrappedMemoLines(TMemo * Memo);
 bool __fastcall DetectSystemExternalEditor(