summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-extended/mc/files/CVE-2021-36370.patch609
-rw-r--r--meta/recipes-extended/mc/mc_4.8.26.bb1
2 files changed, 610 insertions, 0 deletions
diff --git a/meta/recipes-extended/mc/files/CVE-2021-36370.patch b/meta/recipes-extended/mc/files/CVE-2021-36370.patch
new file mode 100644
index 0000000000..d6a26871bd
--- /dev/null
+++ b/meta/recipes-extended/mc/files/CVE-2021-36370.patch
@@ -0,0 +1,609 @@
1Backport patch to fix CVE-2021-36370.
2
3Upstream-Status: Backport [https://github.com/MidnightCommander/mc/commit/9235d3c]
4CVE: CVE-2021-36370
5
6Signed-off-by: Kai Kang <kai.kang@windriver.com>
7
8From 9235d3c232d13ad7f973346077c9cf2eaa77dc5f Mon Sep 17 00:00:00 2001
9From: Andrew Borodin <aborodin@vmail.ru>
10Date: Mon, 12 Jul 2021 08:48:18 +0300
11Subject: [PATCH] SFTPFS: verify server fingerprint (fix CVE-2021-36370).
12
13Use ~/.ssh/known_hosts file to verify server fingerprint
14using ssh way:
15
16$ ssh localhost
17The authenticity of host 'localhost (127.0.0.1)' can't be established.
18ED25519 key fingerprint is SHA256:FzqKTNTroFuNUj1wUzSeV2x/1lpcESnT0ZRCmq5H6o8.
19Are you sure you want to continue connecting (yes/no)? no
20ssh: Host key verification failed.
21
22$ ssh localhost
23The authenticity of host 'localhost (127.0.0.1)' can't be established.
24ED25519 key fingerprint is SHA256:FzqKTNTroFuNUj1wUzSeV2x/1lpcESnT0ZRCmq5H6o8.
25Are you sure you want to continue connecting (yes/no)? yes
26Warning: Permanently added 'localhost' (ED25519) to the list of known hosts.
27andrew@localhost's password:
28
29Thanks the Curl project for the used code.
30
31Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
32Signed-off-by: Yury V. Zaytsev <yury.zaytsev@moneymeets.com>
33---
34 doc/man/mc.1.in | 15 ++
35 doc/man/ru/mc.1.in | 14 ++
36 src/vfs/sftpfs/connection.c | 428 +++++++++++++++++++++++++++++++++++-
37 src/vfs/sftpfs/internal.h | 5 +-
38 4 files changed, 452 insertions(+), 10 deletions(-)
39
40diff --git a/doc/man/mc.1.in b/doc/man/mc.1.in
41index c0c06e32f7..7a3d118384 100644
42--- a/doc/man/mc.1.in
43+++ b/doc/man/mc.1.in
44@@ -3364,6 +3364,21 @@ Examples:
45 sftp://joe@noncompressed.ssh.edu/private
46 sftp://joe@somehost.ssh.edu:2222/private
47 .fi
48+.PP
49+When establishing the connection, server key fingerprint is verified using
50+the ~/.ssh/known_hosts file. If the host/key pair is not found or the host is found,
51+but the key doesn't match, an appropriate message is shown.
52+There are three buttons in the message dialog:
53+.PP
54+.B [Yes]
55+add new host/key pair to the ~/.ssh/known_hosts file and continue.
56+.PP
57+.B [Ignore]
58+do not add new host/key pair to the ~/.ssh/known_hosts file, but continue
59+nevertheless (at you own risk).
60+.PP
61+.B [No]
62+abort connection.
63 .\"NODE " Undelete File System"
64 .SH " Undelete File System"
65 On Linux systems, if you asked configure to use the ext2fs undelete
66diff --git a/doc/man/ru/mc.1.in b/doc/man/ru/mc.1.in
67index 7609da1127..bc0c1810a9 100644
68--- a/doc/man/ru/mc.1.in
69+++ b/doc/man/ru/mc.1.in
70@@ -3874,6 +3874,20 @@ bash\-совместимая оболочка shell.
71 sftp://joe@noncompressed.ssh.edu/private
72 sftp://joe@somehost.ssh.edu:2222/private
73 .fi
74+При установлении соединения происходит проверка ключа сервера с использованием
75+файла ~/.ssh/known_hosts file. Если пара сервер/ключ в этом файле не найдена
76+или сервер найден, но ключ не соответствует, пользователю показывается
77+окно с соответствующим сообщением, содержащее три кнопки:
78+.PP
79+.B [Да]
80+добавить новую пару сервер/ключ в файл ~/.ssh/known_hosts и продолжить соединение.
81+.PP
82+.B [Игнорировать]
83+не добавлять новую пару сервер/ключ в файл ~/.ssh/known_hosts и всё равно
84+продолжить соединение (на свой страх и риск).
85+.PP
86+.B [Нет]
87+прервать соединение.
88 .\"NODE " Undelete File System"
89 .SH " Файловая система UFS (Undelete File System)"
90 В ОС Linux можно сконфигурировать файловую систему ext2fs, используемую
91diff --git a/src/vfs/sftpfs/connection.c b/src/vfs/sftpfs/connection.c
92index 9f8ea5633b..acd5026515 100644
93--- a/src/vfs/sftpfs/connection.c
94+++ b/src/vfs/sftpfs/connection.c
95@@ -42,6 +42,8 @@
96 #include "lib/util.h"
97 #include "lib/tty/tty.h" /* tty_enable_interrupt_key () */
98 #include "lib/vfs/utilvfs.h"
99+#include "lib/mcconfig.h" /* mc_config_get_home_dir () */
100+#include "lib/widget.h" /* query_dialog () */
101
102 #include "internal.h"
103
104@@ -49,10 +51,37 @@
105
106 /*** file scope macro definitions ****************************************************************/
107
108+#define SHA1_DIGEST_LENGTH 20
109+
110 /*** file scope type declarations ****************************************************************/
111
112 /*** file scope variables ************************************************************************/
113
114+#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
115+static const char *const hostkey_method_ssh_ed25519 = "ssh-ed25519";
116+#endif
117+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
118+static const char *const hostkey_method_ssh_ecdsa_521 = "ecdsa-sha2-nistp521";
119+#endif
120+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
121+static const char *const hostkey_method_ssh_ecdsa_384 = "ecdsa-sha2-nistp384";
122+#endif
123+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
124+static const char *const hostkey_method_ssh_ecdsa_256 = "ecdsa-sha2-nistp256";
125+#endif
126+static const char *const hostkey_method_ssh_rsa = "ssh-rsa";
127+static const char *const hostkey_method_ssh_dss = "ssh-dss";
128+
129+/**
130+ *
131+ * The current implementation of know host key checking has following limitations:
132+ *
133+ * - Only plain-text entries are supported (`HashKnownHosts no` OpenSSH option)
134+ * - Only HEX-encoded SHA1 fingerprint display is supported (`FingerprintHash` OpenSSH option)
135+ * - Resolved IP addresses are *not* saved/validated along with the hostnames
136+ *
137+ */
138+
139 static const char *kbi_passwd = NULL;
140 static const struct vfs_s_super *kbi_super = NULL;
141
142@@ -70,9 +99,12 @@ static const struct vfs_s_super *kbi_super = NULL;
143 static int
144 sftpfs_open_socket (struct vfs_s_super *super, GError ** mcerror)
145 {
146+ sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
147 struct addrinfo hints, *res = NULL, *curr_res;
148 int my_socket = 0;
149 char port[BUF_TINY];
150+ static char address_ipv4[INET_ADDRSTRLEN];
151+ static char address_ipv6[INET6_ADDRSTRLEN];
152 int e;
153
154 mc_return_val_if_error (mcerror, LIBSSH2_INVALID_SOCKET);
155@@ -120,6 +152,30 @@ sftpfs_open_socket (struct vfs_s_super *super, GError ** mcerror)
156 {
157 int save_errno;
158
159+ switch (curr_res->ai_addr->sa_family)
160+ {
161+ case AF_INET:
162+ sftpfs_super->ip_address =
163+ inet_ntop (AF_INET, &((struct sockaddr_in *) curr_res->ai_addr)->sin_addr,
164+ address_ipv4, INET_ADDRSTRLEN);
165+ break;
166+ case AF_INET6:
167+ sftpfs_super->ip_address =
168+ inet_ntop (AF_INET6, &((struct sockaddr_in6 *) curr_res->ai_addr)->sin6_addr,
169+ address_ipv6, INET6_ADDRSTRLEN);
170+ break;
171+ default:
172+ sftpfs_super->ip_address = NULL;
173+ }
174+
175+ if (sftpfs_super->ip_address == NULL)
176+ {
177+ mc_propagate_error (mcerror, 0, "%s",
178+ _("sftp: failed to convert remote host IP address into text form"));
179+ my_socket = LIBSSH2_INVALID_SOCKET;
180+ goto ret;
181+ }
182+
183 my_socket = socket (curr_res->ai_family, curr_res->ai_socktype, curr_res->ai_protocol);
184
185 if (my_socket < 0)
186@@ -161,8 +217,358 @@ sftpfs_open_socket (struct vfs_s_super *super, GError ** mcerror)
187 }
188
189 /* --------------------------------------------------------------------------------------------- */
190+
191+/**
192+ * Read ~/.ssh/known_hosts file.
193+ *
194+ * @param super connection data
195+ * @param mcerror pointer to the error handler
196+ * @return TRUE on success, FALSE otherwise
197+ *
198+ * Thanks the Curl project for the code used in this function.
199+ */
200+static gboolean
201+sftpfs_read_known_hosts (struct vfs_s_super *super, GError ** mcerror)
202+{
203+ sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
204+ struct libssh2_knownhost *store = NULL;
205+ int rc;
206+ gboolean found = FALSE;
207+
208+ sftpfs_super->known_hosts = libssh2_knownhost_init (sftpfs_super->session);
209+ if (sftpfs_super->known_hosts == NULL)
210+ goto err;
211+
212+ sftpfs_super->known_hosts_file =
213+ mc_build_filename (mc_config_get_home_dir (), ".ssh", "known_hosts", (char *) NULL);
214+ rc = libssh2_knownhost_readfile (sftpfs_super->known_hosts, sftpfs_super->known_hosts_file,
215+ LIBSSH2_KNOWNHOST_FILE_OPENSSH);
216+ if (rc > 0)
217+ {
218+ const char *kh_name_end = NULL;
219+
220+ while (!found && libssh2_knownhost_get (sftpfs_super->known_hosts, &store, store) == 0)
221+ {
222+ /* For non-standard ports, the name will be enclosed in
223+ * square brackets, followed by a colon and the port */
224+ if (store == NULL)
225+ continue;
226+
227+ if (store->name == NULL)
228+ found = TRUE;
229+ else if (store->name[0] != '[')
230+ found = strcmp (store->name, super->path_element->host) == 0;
231+ else
232+ {
233+ int port;
234+
235+ kh_name_end = strstr (store->name, "]:");
236+ if (kh_name_end == NULL)
237+ /* Invalid host pattern */
238+ continue;
239+
240+ port = (int) g_ascii_strtoll (kh_name_end + 2, NULL, 10);
241+ if (port == super->path_element->port)
242+ {
243+ size_t kh_name_size;
244+
245+ kh_name_size = strlen (store->name) - 1 - strlen (kh_name_end);
246+ found = strncmp (store->name + 1, super->path_element->host, kh_name_size) == 0;
247+ }
248+ }
249+ }
250+ }
251+
252+ if (found)
253+ {
254+ int mask;
255+ const char *hostkey_method = NULL;
256+
257+ mask = store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK;
258+
259+ switch (mask)
260+ {
261+#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
262+ case LIBSSH2_KNOWNHOST_KEY_ED25519:
263+ hostkey_method = hostkey_method_ssh_ed25519;
264+ break;
265+#endif
266+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
267+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
268+ hostkey_method = hostkey_method_ssh_ecdsa_521;
269+ break;
270+#endif
271+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
272+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
273+ hostkey_method = hostkey_method_ssh_ecdsa_384;
274+ break;
275+#endif
276+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
277+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
278+ hostkey_method = hostkey_method_ssh_ecdsa_256;
279+ break;
280+#endif
281+ case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
282+ hostkey_method = hostkey_method_ssh_rsa;
283+ break;
284+ case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
285+ hostkey_method = hostkey_method_ssh_dss;
286+ break;
287+ case LIBSSH2_KNOWNHOST_KEY_RSA1:
288+ mc_propagate_error (mcerror, 0, "%s",
289+ _("sftp: found host key of unsupported type: RSA1"));
290+ return FALSE;
291+ default:
292+ mc_propagate_error (mcerror, 0, "%s %d", _("sftp: unknown host key type:"), mask);
293+ return FALSE;
294+ }
295+
296+ rc = libssh2_session_method_pref (sftpfs_super->session, LIBSSH2_METHOD_HOSTKEY,
297+ hostkey_method);
298+ if (rc < 0)
299+ goto err;
300+ }
301+
302+ return TRUE;
303+
304+ err:
305+ {
306+ int sftp_errno;
307+
308+ sftp_errno = libssh2_session_last_errno (sftpfs_super->session);
309+ sftpfs_ssherror_to_gliberror (sftpfs_super, sftp_errno, mcerror);
310+ }
311+ return FALSE;
312+}
313+
314+/* --------------------------------------------------------------------------------------------- */
315+
316+/**
317+ * Write new host + key pair to the ~/.ssh/known_hosts file.
318+ *
319+ * @param super connection data
320+ * @param remote_key he key for the remote host
321+ * @param remote_key_len length of @remote_key
322+ * @param type_mask info about format of host name, key and key type
323+ * @return 0 on success, regular libssh2 error code otherwise
324+ *
325+ * Thanks the Curl project for the code used in this function.
326+ */
327+static int
328+sftpfs_update_known_hosts (struct vfs_s_super *super, const char *remote_key, size_t remote_key_len,
329+ int type_mask)
330+{
331+ sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
332+ int rc;
333+
334+ /* add this host + key pair */
335+ rc = libssh2_knownhost_addc (sftpfs_super->known_hosts, super->path_element->host, NULL,
336+ remote_key, remote_key_len, NULL, 0, type_mask, NULL);
337+ if (rc < 0)
338+ return rc;
339+
340+ /* write the entire in-memory list of known hosts to the known_hosts file */
341+ rc = libssh2_knownhost_writefile (sftpfs_super->known_hosts, sftpfs_super->known_hosts_file,
342+ LIBSSH2_KNOWNHOST_FILE_OPENSSH);
343+
344+ if (rc < 0)
345+ return rc;
346+
347+ (void) message (D_NORMAL, _("Information"),
348+ _("Permanently added\n%s (%s)\nto the list of known hosts."),
349+ super->path_element->host, sftpfs_super->ip_address);
350+
351+ return 0;
352+}
353+
354+/* --------------------------------------------------------------------------------------------- */
355+/**
356+ * Compute and return readable host key fingerprint hash.
357+ *
358+ * @param session libssh2 session handle
359+ * @return pointer to static buffer on success, NULL otherwise
360+ */
361+static const char *
362+sftpfs_compute_fingerprint_hash (LIBSSH2_SESSION * session)
363+{
364+ static char result[SHA1_DIGEST_LENGTH * 3 + 1]; /* "XX:" for each byte, and EOL */
365+ const char *fingerprint;
366+ size_t i;
367+
368+ /* The fingerprint points to static storage (!), don't free() it. */
369+ fingerprint = libssh2_hostkey_hash (session, LIBSSH2_HOSTKEY_HASH_SHA1);
370+ if (fingerprint == NULL)
371+ return NULL;
372+
373+ for (i = 0; i < SHA1_DIGEST_LENGTH && i * 3 < sizeof (result) - 1; i++)
374+ g_snprintf ((gchar *) (result + i * 3), 4, "%02x:", (guint8) fingerprint[i]);
375+
376+ /* remove last ":" */
377+ result[i * 3 - 1] = '\0';
378+
379+ return result;
380+}
381+
382+/* --------------------------------------------------------------------------------------------- */
383+
384 /**
385- * Recognize authenticaion types supported by remote side and filling internal 'super' structure by
386+ * Process host info found in ~/.ssh/known_hosts file.
387+ *
388+ * @param super connection data
389+ * @param mcerror pointer to the error handler
390+ * @return TRUE on success, FALSE otherwise
391+ *
392+ * Thanks the Curl project for the code used in this function.
393+ */
394+static gboolean
395+sftpfs_process_known_host (struct vfs_s_super *super, GError ** mcerror)
396+{
397+ sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
398+ const char *remote_key;
399+ const char *key_type;
400+ const char *fingerprint_hash;
401+ size_t remote_key_len = 0;
402+ int remote_key_type = LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
403+ int keybit = 0;
404+ struct libssh2_knownhost *host = NULL;
405+ int rc;
406+ char *msg = NULL;
407+ gboolean handle_query = FALSE;
408+
409+ remote_key = libssh2_session_hostkey (sftpfs_super->session, &remote_key_len, &remote_key_type);
410+ if (remote_key == NULL || remote_key_len == 0
411+ || remote_key_type == LIBSSH2_HOSTKEY_TYPE_UNKNOWN)
412+ {
413+ mc_propagate_error (mcerror, 0, "%s", _("sftp: cannot get the remote host key"));
414+ return FALSE;
415+ }
416+
417+ switch (remote_key_type)
418+ {
419+ case LIBSSH2_HOSTKEY_TYPE_RSA:
420+ keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
421+ key_type = "RSA";
422+ break;
423+ case LIBSSH2_HOSTKEY_TYPE_DSS:
424+ keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
425+ key_type = "DSS";
426+ break;
427+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
428+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
429+ keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
430+ key_type = "ECDSA";
431+ break;
432+#endif
433+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
434+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
435+ keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
436+ key_type = "ECDSA";
437+ break;
438+#endif
439+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521
440+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
441+ keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
442+ key_type = "ECDSA";
443+ break;
444+#endif
445+#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
446+ case LIBSSH2_HOSTKEY_TYPE_ED25519:
447+ keybit = LIBSSH2_KNOWNHOST_KEY_ED25519;
448+ key_type = "ED25519";
449+ break;
450+#endif
451+ default:
452+ mc_propagate_error (mcerror, 0, "%s",
453+ _("sftp: unsupported key type, can't check remote host key"));
454+ return FALSE;
455+ }
456+
457+ fingerprint_hash = sftpfs_compute_fingerprint_hash (sftpfs_super->session);
458+ if (fingerprint_hash == NULL)
459+ {
460+ mc_propagate_error (mcerror, 0, "%s", _("sftp: can't compute host key fingerprint hash"));
461+ return FALSE;
462+ }
463+
464+ rc = libssh2_knownhost_checkp (sftpfs_super->known_hosts, super->path_element->host,
465+ super->path_element->port, remote_key, remote_key_len,
466+ LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW |
467+ keybit, &host);
468+
469+ switch (rc)
470+ {
471+ default:
472+ case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
473+ /* something prevented the check to be made */
474+ goto err;
475+
476+ case LIBSSH2_KNOWNHOST_CHECK_MATCH:
477+ /* host + key pair matched -- OK */
478+ break;
479+
480+ case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
481+ /* no host match was found -- add it to the known_hosts file */
482+ msg = g_strdup_printf (_("The authenticity of host\n%s (%s)\ncan't be established!\n"
483+ "%s key fingerprint hash is\nSHA1:%s.\n"
484+ "Do you want to add it to the list of known hosts and continue connecting?"),
485+ super->path_element->host, sftpfs_super->ip_address,
486+ key_type, fingerprint_hash);
487+ /* Select "No" initially */
488+ query_set_sel (2);
489+ rc = query_dialog (_("Warning"), msg, D_NORMAL, 3, _("&Yes"), _("&Ignore"), _("&No"));
490+ g_free (msg);
491+ handle_query = TRUE;
492+ break;
493+
494+ case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
495+ msg = g_strdup_printf (_("%s (%s)\nis found in the list of known hosts but\n"
496+ "KEYS DO NOT MATCH! THIS COULD BE A MITM ATTACK!\n"
497+ "Are you sure you want to add it to the list of known hosts and continue connecting?"),
498+ super->path_element->host, sftpfs_super->ip_address);
499+ /* Select "No" initially */
500+ query_set_sel (2);
501+ rc = query_dialog (MSG_ERROR, msg, D_ERROR, 3, _("&Yes"), _("&Ignore"), _("&No"));
502+ g_free (msg);
503+ handle_query = TRUE;
504+ break;
505+ }
506+
507+ if (handle_query)
508+ switch (rc)
509+ {
510+ case 0:
511+ /* Yes: add this host + key pair, continue connecting */
512+ if (sftpfs_update_known_hosts (super, remote_key, remote_key_len,
513+ LIBSSH2_KNOWNHOST_TYPE_PLAIN
514+ | LIBSSH2_KNOWNHOST_KEYENC_RAW | keybit) < 0)
515+ goto err;
516+ break;
517+ case 1:
518+ /* Ignore: do not add this host + key pair, continue connecting anyway */
519+ break;
520+ case 2:
521+ default:
522+ mc_propagate_error (mcerror, 0, "%s", _("sftp: host key verification failed"));
523+ /* No: abort connection */
524+ goto err;
525+ }
526+
527+ return TRUE;
528+
529+ err:
530+ {
531+ int sftp_errno;
532+
533+ sftp_errno = libssh2_session_last_errno (sftpfs_super->session);
534+ sftpfs_ssherror_to_gliberror (sftpfs_super, sftp_errno, mcerror);
535+ }
536+
537+ return FALSE;
538+}
539+
540+/* --------------------------------------------------------------------------------------------- */
541+/**
542+ * Recognize authentication types supported by remote side and filling internal 'super' structure by
543 * proper enum's values.
544 *
545 * @param super connection data
546@@ -461,6 +867,9 @@ sftpfs_open_connection (struct vfs_s_super *super, GError ** mcerror)
547 if (sftpfs_super->session == NULL)
548 return (-1);
549
550+ if (!sftpfs_read_known_hosts (super, mcerror))
551+ return (-1);
552+
553 /* ... start it up. This will trade welcome banners, exchange keys,
554 * and setup crypto, compression, and MAC layers
555 */
556@@ -475,13 +884,8 @@ sftpfs_open_connection (struct vfs_s_super *super, GError ** mcerror)
557 return (-1);
558 }
559
560- /* At this point we havn't yet authenticated. The first thing to do
561- * is check the hostkey's fingerprint against our known hosts Your app
562- * may have it hard coded, may go to a file, may present it to the
563- * user, that's your call
564- */
565- sftpfs_super->fingerprint =
566- libssh2_hostkey_hash (sftpfs_super->session, LIBSSH2_HOSTKEY_HASH_SHA1);
567+ if (!sftpfs_process_known_host (super, mcerror))
568+ return (-1);
569
570 if (!sftpfs_recognize_auth_types (super))
571 {
572@@ -538,7 +942,13 @@ sftpfs_close_connection (struct vfs_s_super *super, const char *shutdown_message
573 sftpfs_super->agent = NULL;
574 }
575
576- sftpfs_super->fingerprint = NULL;
577+ if (sftpfs_super->known_hosts != NULL)
578+ {
579+ libssh2_knownhost_free (sftpfs_super->known_hosts);
580+ sftpfs_super->known_hosts = NULL;
581+ }
582+
583+ MC_PTR_FREE (sftpfs_super->known_hosts_file);
584
585 if (sftpfs_super->session != NULL)
586 {
587diff --git a/src/vfs/sftpfs/internal.h b/src/vfs/sftpfs/internal.h
588index 5616fb8990..643ce5e3cc 100644
589--- a/src/vfs/sftpfs/internal.h
590+++ b/src/vfs/sftpfs/internal.h
591@@ -42,6 +42,9 @@ typedef struct
592 sftpfs_auth_type_t auth_type;
593 sftpfs_auth_type_t config_auth_type;
594
595+ LIBSSH2_KNOWNHOSTS *known_hosts;
596+ char *known_hosts_file;
597+
598 LIBSSH2_SESSION *session;
599 LIBSSH2_SFTP *sftp_session;
600
601@@ -51,7 +54,7 @@ typedef struct
602 char *privkey;
603
604 int socket_handle;
605- const char *fingerprint;
606+ const char *ip_address;
607 vfs_path_element_t *original_connection_info;
608 } sftpfs_super_t;
609
diff --git a/meta/recipes-extended/mc/mc_4.8.26.bb b/meta/recipes-extended/mc/mc_4.8.26.bb
index 5c5e6790d8..6bc7e6e8e1 100644
--- a/meta/recipes-extended/mc/mc_4.8.26.bb
+++ b/meta/recipes-extended/mc/mc_4.8.26.bb
@@ -11,6 +11,7 @@ RRECOMMENDS_${PN} = "ncurses-terminfo"
11SRC_URI = "http://www.midnight-commander.org/downloads/${BPN}-${PV}.tar.bz2 \ 11SRC_URI = "http://www.midnight-commander.org/downloads/${BPN}-${PV}.tar.bz2 \
12 file://0001-mc-replace-perl-w-with-use-warnings.patch \ 12 file://0001-mc-replace-perl-w-with-use-warnings.patch \
13 file://nomandate.patch \ 13 file://nomandate.patch \
14 file://CVE-2021-36370.patch \
14 " 15 "
15SRC_URI[sha256sum] = "9d6358d0a351a455a1410aab57f33b6b48b0fcf31344b9a10b0ff497595979d1" 16SRC_URI[sha256sum] = "9d6358d0a351a455a1410aab57f33b6b48b0fcf31344b9a10b0ff497595979d1"
16 17