Browse Source

Reimplementing host key algorithm display for /info in a way that does not need reorganizing PuTTY code to show them in the preference order

Side effect of this is that Ed448 is put correctly on the top

Source commit: da86732db01cdd2c7bd228ec7596097590af1ce9
Martin Prikryl 3 years ago
parent
commit
68a4dd04b7

+ 33 - 13
source/core/PuttyIntf.cpp

@@ -947,7 +947,7 @@ static void __fastcall DoNormalizeFingerprint(UnicodeString & Fingerprint, Unico
   int Count;
   // We may use find_pubkey_alg, but it gets complicated with normalized fingerprint
   // as the names have different number of dashes
-  get_hostkey_algs(&Count, &SignKeys);
+  get_hostkey_algs(-1, &Count, &SignKeys);
   try
   {
     for (int Index = 0; Index < Count; Index++)
@@ -1151,24 +1151,44 @@ TStrings * SshKexList()
   return Result.release();
 }
 //---------------------------------------------------------------------------
+int HostKeyToPutty(THostKey HostKey)
+{
+  int Result;
+  switch (HostKey)
+  {
+    case hkWarn: Result = HK_WARN; break;
+    case hkRSA: Result = HK_RSA; break;
+    case hkDSA: Result = hkDSA; break;
+    case hkECDSA: Result = HK_ECDSA; break;
+    case hkED25519: Result = HK_ED25519; break;
+    case hkED448: Result = HK_ED448; break;
+    default: Result = -1; DebugFail();
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------
 TStrings * SshHostKeyList()
 {
   std::unique_ptr<TStrings> Result(new TStringList());
-  cp_ssh_keyalg * SignKeys;
-  int Count;
-  get_hostkey_algs(&Count, &SignKeys);
-  try
+  for (int DefaultIndex = 0; DefaultIndex < HOSTKEY_COUNT; DefaultIndex++)
   {
-    for (int Index = 0; Index < Count; Index++)
+    int Type = HostKeyToPutty(DefaultHostKeyList[DefaultIndex]);
+    cp_ssh_keyalg * SignKeys;
+    int Count;
+    get_hostkey_algs(Type, &Count, &SignKeys);
+    try
     {
-      cp_ssh_keyalg SignKey = SignKeys[Index];
-      UnicodeString Name = UnicodeString(SignKey->ssh_id);
-      Result->Add(Name);
+      for (int Index = 0; Index < Count; Index++)
+      {
+        cp_ssh_keyalg SignKey = SignKeys[Index];
+        UnicodeString Name = UnicodeString(SignKey->ssh_id);
+        Result->Add(Name);
+      }
+    }
+    __finally
+    {
+      sfree(SignKeys);
     }
-  }
-  __finally
-  {
-    sfree(SignKeys);
   }
   return Result.release();
 }

+ 3 - 0
source/core/PuttyTools.h

@@ -2,6 +2,8 @@
 #ifndef PuttyToolsH
 #define PuttyToolsH
 //---------------------------------------------------------------------------
+#include <SessionData.h>
+//---------------------------------------------------------------------------
 enum TKeyType
 {
   ktUnopenable, ktUnknown,
@@ -43,6 +45,7 @@ bool IsOpenSSH(const UnicodeString & SshImplementation);
 //---------------------------------------------------------------------------
 TStrings * SshCipherList();
 TStrings * SshKexList();
+int HostKeyToPutty(THostKey HostKey);
 TStrings * SshHostKeyList();
 TStrings * SshMacList();
 //---------------------------------------------------------------------------

+ 1 - 10
source/core/SecureShell.cpp

@@ -222,16 +222,7 @@ Conf * __fastcall TSecureShell::StoreToConfig(TSessionData * Data, bool Simple)
   DebugAssert(HK_MAX == HOSTKEY_COUNT);
   for (int h = 0; h < HOSTKEY_COUNT; h++)
   {
-    int phk;
-    switch (Data->HostKeys[h]) {
-      case hkWarn: phk = HK_WARN; break;
-      case hkRSA: phk = HK_RSA; break;
-      case hkDSA: phk = hkDSA; break;
-      case hkECDSA: phk = HK_ECDSA; break;
-      case hkED25519: phk = HK_ED25519; break;
-      case hkED448: phk = HK_ED448; break;
-      default: DebugFail();
-    }
+    int phk = HostKeyToPutty(Data->HostKeys[h]);
     conf_set_int_int(conf, CONF_ssh_hklist, h, phk);
   }
 

+ 1 - 1
source/putty/puttyexp.h

@@ -20,7 +20,7 @@ const struct ssh_decompressor * get_sccomp(Backend * be);
 unsigned int winscp_query(Backend * be, int query);
 void md5checksum(const char * buffer, int len, unsigned char output[16]);
 typedef const struct ssh_keyalg * cp_ssh_keyalg;
-void get_hostkey_algs(int * count, cp_ssh_keyalg ** sign_keys);
+void get_hostkey_algs(int type, int * count, cp_ssh_keyalg ** sign_keys);
 void get_macs(int * count, const struct ssh2_macalg *** amacs);
 int have_any_ssh2_hostkey(Seat * seat, const char * host, int port);
 

+ 10 - 5
source/putty/ssh/transport2.c

@@ -2479,14 +2479,19 @@ void call_ssh_timer(Backend * be)
 }
 
 // WINSCP
-void get_hostkey_algs(int * count, cp_ssh_keyalg ** sign_keys)
+void get_hostkey_algs(int type, int * count, cp_ssh_keyalg ** sign_keys)
 {
     int i;
-    *count = lenof(ssh2_hostkey_algs);
-    *sign_keys = snewn(*count, cp_ssh_keyalg *);
-    for (i = 0; i < *count; i++)
+    int max = lenof(ssh2_hostkey_algs);
+    *count = 0;
+    *sign_keys = snewn(max, cp_ssh_keyalg *);
+    for (i = 0; i < max; i++)
     {
-        *((*sign_keys) + i) = ssh2_hostkey_algs[i].alg;
+        if ((type < 0) || (ssh2_hostkey_algs[i].id == type))
+        {
+            *((*sign_keys) + (*count)) = ssh2_hostkey_algs[i].alg;
+            (*count)++;
+        }
     }
 }
 

+ 1 - 2
source/putty/ssh/transport2.h

@@ -55,11 +55,10 @@ struct kexinit_algorithm_list {
     X(HK_ECDSA, ssh_ecdsa_nistp256)                             \
     X(HK_ECDSA, ssh_ecdsa_nistp384)                             \
     X(HK_ECDSA, ssh_ecdsa_nistp521)                             \
-    /* Changed order to match WinSCP default preference list for SshHostKeyList() */ \
+    X(HK_DSA, ssh_dsa)                                          \
     X(HK_RSA, ssh_rsa_sha512)                                   \
     X(HK_RSA, ssh_rsa_sha256)                                   \
     X(HK_RSA, ssh_rsa)                                          \
-    X(HK_DSA, ssh_dsa)                          \
     X(HK_ED25519, opensshcert_ssh_ecdsa_ed25519)                \
     /* OpenSSH defines no certified version of Ed448 */         \
     X(HK_ECDSA, opensshcert_ssh_ecdsa_nistp256)                 \