Browse Source

Bug 1833: Cannot connect to SSH-1 servers

https://winscp.net/tracker/1833

Source commit: ba032585e748ac2590bce428c1c74b0c76c9aeb9
Martin Prikryl 5 years ago
parent
commit
5a54aaf111

+ 7 - 1
source/core/PuttyIntf.cpp

@@ -946,6 +946,11 @@ UnicodeString __fastcall ParseOpenSshPubLine(const UnicodeString & Line, const s
   return Result;
   return Result;
 }
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
+UnicodeString __fastcall GetSsh1KeyType()
+{
+  return UnicodeString(ssh_rsa.cache_id);
+}
+//---------------------------------------------------------------------------
 UnicodeString __fastcall GetKeyTypeHuman(const UnicodeString & KeyType)
 UnicodeString __fastcall GetKeyTypeHuman(const UnicodeString & KeyType)
 {
 {
   UnicodeString Result;
   UnicodeString Result;
@@ -953,7 +958,8 @@ UnicodeString __fastcall GetKeyTypeHuman(const UnicodeString & KeyType)
   {
   {
     Result = L"DSA";
     Result = L"DSA";
   }
   }
-  else if (KeyType == ssh_rsa.cache_id)
+  else if ((KeyType == ssh_rsa.cache_id) ||
+           (KeyType == L"rsa")) // SSH1
   {
   {
     Result = L"RSA";
     Result = L"RSA";
   }
   }

+ 1 - 0
source/core/PuttyTools.h

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

+ 20 - 4
source/core/SecureShell.cpp

@@ -2297,12 +2297,28 @@ void __fastcall TSecureShell::VerifyHostKey(
   GetRealHost(Host, Port);
   GetRealHost(Host, Port);
 
 
   UnicodeString Buf = Fingerprint;
   UnicodeString Buf = Fingerprint;
-  UnicodeString SignKeyAlg = CutToChar(Buf, L' ', false);
-  UnicodeString SignKeySize = CutToChar(Buf, L' ', false);
+  UnicodeString SignKeyAlg, SignKeySize, MD5, SHA256;
+  if (get_ssh_version(FBackendHandle) == 1)
+  {
+    SignKeyAlg = GetSsh1KeyType();
+  }
+  else
+  {
+    SignKeyAlg = CutToChar(Buf, L' ', false);
+  }
+  SignKeySize = CutToChar(Buf, L' ', false);
+  MD5 = CutToChar(Buf, L' ', false);
+  if (get_ssh_version(FBackendHandle) == 1)
+  {
+    SHA256 = L"-";
+    DebugAssert(Buf.IsEmpty());
+  }
+  else
+  {
+    SHA256 = Buf;
+  }
   UnicodeString SignKeyType = SignKeyAlg + L' ' + SignKeySize;
   UnicodeString SignKeyType = SignKeyAlg + L' ' + SignKeySize;
-  UnicodeString MD5 = CutToChar(Buf, L' ', false);
   UnicodeString FingerprintMD5 = SignKeyType + L' ' + MD5;
   UnicodeString FingerprintMD5 = SignKeyType + L' ' + MD5;
-  UnicodeString SHA256 = Buf;
   UnicodeString FingerprintSHA256 = SignKeyType + L' ' + SHA256;
   UnicodeString FingerprintSHA256 = SignKeyType + L' ' + SHA256;
 
 
   FSessionInfo.HostKeyFingerprintSHA256 = FingerprintSHA256;
   FSessionInfo.HostKeyFingerprintSHA256 = FingerprintSHA256;

+ 29 - 1
source/putty/ssh1connection.c

@@ -37,6 +37,7 @@ static void ssh1_connection_special_cmd(PacketProtocolLayer *ppl,
 static bool ssh1_connection_want_user_input(PacketProtocolLayer *ppl);
 static bool ssh1_connection_want_user_input(PacketProtocolLayer *ppl);
 static void ssh1_connection_got_user_input(PacketProtocolLayer *ppl);
 static void ssh1_connection_got_user_input(PacketProtocolLayer *ppl);
 static void ssh1_connection_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
 static void ssh1_connection_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
+static unsigned int ssh1_connection_winscp_query(PacketProtocolLayer *ppl, int query);
 
 
 static const struct PacketProtocolLayerVtable ssh1_connection_vtable = {
 static const struct PacketProtocolLayerVtable ssh1_connection_vtable = {
     ssh1_connection_free,
     ssh1_connection_free,
@@ -47,6 +48,7 @@ static const struct PacketProtocolLayerVtable ssh1_connection_vtable = {
     ssh1_connection_got_user_input,
     ssh1_connection_got_user_input,
     ssh1_connection_reconfigure,
     ssh1_connection_reconfigure,
     NULL /* no layer names in SSH-1 */,
     NULL /* no layer names in SSH-1 */,
+    ssh1_connection_winscp_query,
 };
 };
 
 
 static void ssh1_rportfwd_remove(
 static void ssh1_rportfwd_remove(
@@ -217,7 +219,7 @@ static void ssh1_connection_free(PacketProtocolLayer *ppl)
     if (s->antispoof_prompt)
     if (s->antispoof_prompt)
         free_prompts(s->antispoof_prompt);
         free_prompts(s->antispoof_prompt);
 
 
-    delete_callbacks_for_context(ppl->seat, s);
+    delete_callbacks_for_context(get_seat_callback_set(ppl->seat), s);
 
 
     sfree(s);
     sfree(s);
 }
 }
@@ -843,3 +845,29 @@ static void ssh1_connection_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
     if (s->portfwdmgr_configured)
     if (s->portfwdmgr_configured)
         portfwdmgr_config(s->portfwdmgr, s->conf);
         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;
+    }
+}

+ 22 - 0
source/putty/ssh1login.c

@@ -71,6 +71,7 @@ static void ssh1_login_special_cmd(PacketProtocolLayer *ppl,
 static bool ssh1_login_want_user_input(PacketProtocolLayer *ppl);
 static bool ssh1_login_want_user_input(PacketProtocolLayer *ppl);
 static void ssh1_login_got_user_input(PacketProtocolLayer *ppl);
 static void ssh1_login_got_user_input(PacketProtocolLayer *ppl);
 static void ssh1_login_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
 static void ssh1_login_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
+static unsigned int ssh1_login_winscp_query(PacketProtocolLayer *ppl, int query);
 
 
 static const struct PacketProtocolLayerVtable ssh1_login_vtable = {
 static const struct PacketProtocolLayerVtable ssh1_login_vtable = {
     ssh1_login_free,
     ssh1_login_free,
@@ -81,6 +82,7 @@ static const struct PacketProtocolLayerVtable ssh1_login_vtable = {
     ssh1_login_got_user_input,
     ssh1_login_got_user_input,
     ssh1_login_reconfigure,
     ssh1_login_reconfigure,
     NULL /* no layer names in SSH-1 */,
     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_query(struct ssh1_login_state *s, strbuf *req);
@@ -1187,3 +1189,23 @@ static void ssh1_login_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
         container_of(ppl, struct ssh1_login_state, ppl);
         container_of(ppl, struct ssh1_login_state, ppl);
     ssh_ppl_reconfigure(s->successor_layer, conf);
     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;
+    }
+}