diff --git a/.gitignore b/.gitignore
index 9130fdb..bfd0bb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-SOURCES/libssh-0.9.0.tar.xz
+SOURCES/libssh-0.9.4.tar.xz
 SOURCES/libssh.keyring
diff --git a/.libssh.metadata b/.libssh.metadata
index 2c4bf88..c453642 100644
--- a/.libssh.metadata
+++ b/.libssh.metadata
@@ -1,2 +1,2 @@
-570bffef68af6c1211673bc9a8036c9265935b2b SOURCES/libssh-0.9.0.tar.xz
+93289b77379263328c843fa85ba5ed4b274b689f SOURCES/libssh-0.9.4.tar.xz
 3f2ab0bca02893402ba0ad172a6bd44456a65f86 SOURCES/libssh.keyring
diff --git a/SOURCES/libssh-0.9.0-do-not-ignore-known-hosts-keys.patch b/SOURCES/libssh-0.9.0-do-not-ignore-known-hosts-keys.patch
deleted file mode 100644
index c007677..0000000
--- a/SOURCES/libssh-0.9.0-do-not-ignore-known-hosts-keys.patch
+++ /dev/null
@@ -1,1240 +0,0 @@
-From b040856ccfde1a5d4c21791f46ca6ee00c21a47b Mon Sep 17 00:00:00 2001
-From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Date: Tue, 2 Jul 2019 10:21:15 +0200
-Subject: [PATCH 1/6] knownhosts: Fix possible memory leak
-
-The memory allocated for host_port can leak if the global knownhosts
-file is unaccessible.
-
-Found by address sanitizer build in CI.
-
-Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Reviewed-by: Jakub Jelen <jjelen@redhat.com>
-(cherry picked from commit fe248414fec1e654e4ee1259927d68777dd870ae)
----
- src/knownhosts.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/src/knownhosts.c b/src/knownhosts.c
-index 8a4a8ba7..9383cc97 100644
---- a/src/knownhosts.c
-+++ b/src/knownhosts.c
-@@ -706,13 +706,15 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
-         rc = ssh_known_hosts_read_entries(host_port,
-                                           session->opts.global_knownhosts,
-                                           &entry_list);
--        SAFE_FREE(host_port);
-         if (rc != 0) {
-+            SAFE_FREE(host_port);
-             ssh_list_free(entry_list);
-             return SSH_KNOWN_HOSTS_ERROR;
-         }
-     }
- 
-+    SAFE_FREE(host_port);
-+
-     if (ssh_list_count(entry_list) == 0) {
-         ssh_list_free(entry_list);
-         return SSH_KNOWN_HOSTS_UNKNOWN;
--- 
-2.21.0
-
-
-From 7ff0af75436ee6e549907dd563e968b92f7f8db2 Mon Sep 17 00:00:00 2001
-From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Date: Fri, 28 Jun 2019 13:19:51 +0200
-Subject: [PATCH 2/6] tests: Check if known_hosts works with single
- unaccessible file
-
-Make sure known hosts check works when local known_hosts file is
-unaccessible, but the host is present in global known_hosts file.
-
-Remove double return value check in previous existing test.
-
-Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Reviewed-by: Jakub Jelen <jjelen@redhat.com>
-(cherry picked from commit ad68de7271e6ccda261df4d9fc827321e7d90fd0)
----
- tests/unittests/torture_knownhosts_parsing.c | 19 +++++++++++--------
- 1 file changed, 11 insertions(+), 8 deletions(-)
-
-diff --git a/tests/unittests/torture_knownhosts_parsing.c b/tests/unittests/torture_knownhosts_parsing.c
-index ac8d7f31..a087caef 100644
---- a/tests/unittests/torture_knownhosts_parsing.c
-+++ b/tests/unittests/torture_knownhosts_parsing.c
-@@ -384,22 +384,19 @@ static void torture_knownhosts_host_exists(void **state)
- 
-     /* This makes sure the system's known_hosts are not used */
-     ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, "/dev/null");
--
-     found = ssh_session_has_known_hosts_entry(session);
-     assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
--    assert_true(found == SSH_KNOWN_HOSTS_OK);
- 
-     /* This makes sure the check will not fail when the system's known_hosts is
-      * not accessible*/
-     ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, "./unaccessible");
--
-     found = ssh_session_has_known_hosts_entry(session);
-     assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
--    assert_true(found == SSH_KNOWN_HOSTS_OK);
- 
-+    /* This makes sure the check will fail for an unknown host */
-     ssh_options_set(session, SSH_OPTIONS_HOST, "wurstbrot");
-     found = ssh_session_has_known_hosts_entry(session);
--    assert_true(found == SSH_KNOWN_HOSTS_UNKNOWN);
-+    assert_int_equal(found, SSH_KNOWN_HOSTS_UNKNOWN);
- 
-     ssh_free(session);
- }
-@@ -414,17 +411,23 @@ static void torture_knownhosts_host_exists_global(void **state)
-     assert_non_null(session);
- 
-     ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
-+    ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, knownhosts_file);
-+
-     /* This makes sure the user's known_hosts are not used */
-     ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "/dev/null");
--    ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, knownhosts_file);
-+    found = ssh_session_has_known_hosts_entry(session);
-+    assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
- 
-+    /* This makes sure the check will not fail when the user's known_hosts is
-+     * not accessible*/
-+    ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "./unaccessible");
-     found = ssh_session_has_known_hosts_entry(session);
-     assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
--    assert_true(found == SSH_KNOWN_HOSTS_OK);
- 
-+    /* This makes sure the check will fail for an unknown host */
-     ssh_options_set(session, SSH_OPTIONS_HOST, "wurstbrot");
-     found = ssh_session_has_known_hosts_entry(session);
--    assert_true(found == SSH_KNOWN_HOSTS_UNKNOWN);
-+    assert_int_equal(found, SSH_KNOWN_HOSTS_UNKNOWN);
- 
-     ssh_free(session);
- }
--- 
-2.21.0
-
-
-From b9530cedbeb169762307096dfeb485ab94e09740 Mon Sep 17 00:00:00 2001
-From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Date: Fri, 28 Jun 2019 13:27:34 +0200
-Subject: [PATCH 3/6] knownhosts: Read knownhosts file only if found
-
-Avoid trying to open the files if they are not accessible.  This was
-already treated as a non-error, but with this we save one function call.
-
-Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Reviewed-by: Jakub Jelen <jjelen@redhat.com>
-(cherry picked from commit e5a64a3d6b1b601cbaf207468a6658d1a4fa0031)
----
- src/knownhosts.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/src/knownhosts.c b/src/knownhosts.c
-index 9383cc97..8040a0c0 100644
---- a/src/knownhosts.c
-+++ b/src/knownhosts.c
-@@ -691,7 +691,7 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
-         return SSH_KNOWN_HOSTS_ERROR;
-     }
- 
--    if (session->opts.knownhosts != NULL) {
-+    if (known_hosts_found) {
-         rc = ssh_known_hosts_read_entries(host_port,
-                                           session->opts.knownhosts,
-                                           &entry_list);
-@@ -702,7 +702,7 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
-         }
-     }
- 
--    if (session->opts.global_knownhosts != NULL) {
-+    if (global_known_hosts_found) {
-         rc = ssh_known_hosts_read_entries(host_port,
-                                           session->opts.global_knownhosts,
-                                           &entry_list);
--- 
-2.21.0
-
-
-From aaa978ad06ebdeff88a39b9a894696254263162c Mon Sep 17 00:00:00 2001
-From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Date: Fri, 28 Jun 2019 22:35:38 +0200
-Subject: [PATCH 4/6] token: Added function to remove duplicates
-
-Added a function to remove duplicates from lists.  This function is used
-in a new provided function to append lists removing duplicates.
-
-Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Reviewed-by: Jakub Jelen <jjelen@redhat.com>
-(cherry picked from commit 548753b3389518ebce98a7ddbf0640db3ad72de8)
----
- include/libssh/token.h           |   6 +-
- src/token.c                      | 152 ++++++++++++++++++++++++++++++-
- tests/unittests/torture_tokens.c | 122 +++++++++++++++++++++++++
- 3 files changed, 278 insertions(+), 2 deletions(-)
-
-diff --git a/include/libssh/token.h b/include/libssh/token.h
-index 7b244189..9896fb06 100644
---- a/include/libssh/token.h
-+++ b/include/libssh/token.h
-@@ -38,7 +38,11 @@ void ssh_tokens_free(struct ssh_tokens_st *tokens);
- char *ssh_find_matching(const char *available_d,
-                         const char *preferred_d);
- 
--
- char *ssh_find_all_matching(const char *available_d,
-                             const char *preferred_d);
-+
-+char *ssh_remove_duplicates(const char *list);
-+
-+char *ssh_append_without_duplicates(const char *list,
-+                                    const char *appended_list);
- #endif /* TOKEN_H_ */
-diff --git a/src/token.c b/src/token.c
-index aee235ac..0924d3bd 100644
---- a/src/token.c
-+++ b/src/token.c
-@@ -26,6 +26,7 @@
- 
- #include <stdio.h>
- #include <string.h>
-+#include <stdbool.h>
- 
- #include "libssh/priv.h"
- #include "libssh/token.h"
-@@ -175,7 +176,7 @@ char *ssh_find_matching(const char *available_list,
- 
-     for (i = 0; p_tok->tokens[i]; i++) {
-         for (j = 0; a_tok->tokens[j]; j++) {
--            if (strcmp(a_tok->tokens[j], p_tok->tokens[i]) == 0){
-+            if (strcmp(a_tok->tokens[j], p_tok->tokens[i]) == 0) {
-                 ret = strdup(a_tok->tokens[j]);
-                 goto out;
-             }
-@@ -260,3 +261,152 @@ out:
-     ssh_tokens_free(p_tok);
-     return ret;
- }
-+
-+/**
-+ * @internal
-+ *
-+ * @brief Given a string containing a list of elements, remove all duplicates
-+ * and return in a newly allocated string.
-+ *
-+ * @param[in] list  The list to be freed of duplicates
-+ *
-+ * @return  A newly allocated copy of the string free of duplicates; NULL in
-+ * case of error.
-+ */
-+char *ssh_remove_duplicates(const char *list)
-+{
-+    struct ssh_tokens_st *tok = NULL;
-+
-+    size_t i, j, num_tokens, max_len;
-+    char *ret = NULL;
-+    bool *should_copy = NULL, need_comma = false;
-+
-+    if (list == NULL) {
-+        return NULL;
-+    }
-+
-+    /* The maximum number of tokens is the size of the list */
-+    max_len = strlen(list);
-+    if (max_len == 0) {
-+        return NULL;
-+    }
-+
-+    /* Add space for ending '\0' */
-+    max_len++;
-+
-+    tok = ssh_tokenize(list, ',');
-+    if ((tok == NULL) || (tok->tokens == NULL) || (tok->tokens[0] == NULL)) {
-+        goto out;
-+    }
-+
-+    should_copy = calloc(1, max_len);
-+    if (should_copy == NULL) {
-+        goto out;
-+    }
-+
-+    if (strlen(tok->tokens[0]) > 0) {
-+        should_copy[0] = true;
-+    }
-+
-+    for (i = 1; tok->tokens[i]; i++) {
-+        for (j = 0; j < i; j++) {
-+            if (strcmp(tok->tokens[i], tok->tokens[j]) == 0) {
-+                /* Found a duplicate; do not copy */
-+                should_copy[i] = false;
-+                break;
-+            }
-+        }
-+
-+        /* No matching token before */
-+        if (j == i) {
-+            /* Only copy if it is not an empty string */
-+            if (strlen(tok->tokens[i]) > 0) {
-+                should_copy[i] = true;
-+            } else {
-+                should_copy[i] = false;
-+            }
-+        }
-+    }
-+
-+    num_tokens = i;
-+
-+    ret = calloc(1, max_len);
-+    if (ret == NULL) {
-+        goto out;
-+    }
-+
-+    for (i = 0; i < num_tokens; i++) {
-+        if (should_copy[i]) {
-+            if (need_comma) {
-+                strncat(ret, ",", (max_len - strlen(ret) - 1));
-+            }
-+            strncat(ret, tok->tokens[i], (max_len - strlen(ret) - 1));
-+            need_comma = true;
-+        }
-+    }
-+
-+    /* If no comma is needed, nothing was copied */
-+    if (!need_comma) {
-+        SAFE_FREE(ret);
-+    }
-+
-+out:
-+    SAFE_FREE(should_copy);
-+    ssh_tokens_free(tok);
-+    return ret;
-+}
-+
-+/**
-+ * @internal
-+ *
-+ * @brief Given two strings containing lists of tokens, return a newly
-+ * allocated string containing all the elements of the first list appended with
-+ * all the elements of the second list, without duplicates. The order of the
-+ * elements will be preserved.
-+ *
-+ * @param[in] list             The first list
-+ * @param[in] appended_list    The list to be appended
-+ *
-+ * @return  A newly allocated copy list containing all the elements of the
-+ * kept_list appended with the elements of the appended_list without duplicates;
-+ * NULL in case of error.
-+ */
-+char *ssh_append_without_duplicates(const char *list,
-+                                    const char *appended_list)
-+{
-+    size_t concat_len = 0;
-+    char *ret = NULL, *concat = NULL;
-+
-+    if (list != NULL) {
-+        concat_len = strlen(list);
-+    }
-+
-+    if (appended_list != NULL) {
-+        concat_len += strlen(appended_list);
-+    }
-+
-+    if (concat_len == 0) {
-+        return NULL;
-+    }
-+
-+    /* Add room for ending '\0' and for middle ',' */
-+    concat_len += 2;
-+    concat = calloc(1, concat_len);
-+    if (concat == NULL) {
-+        return NULL;
-+    }
-+
-+    if (list != NULL) {
-+        strcpy(concat, list);
-+        strncat(concat, ",", concat_len - strlen(concat) - 1);
-+    }
-+    if (appended_list != NULL) {
-+        strncat(concat, appended_list, concat_len - strlen(concat) - 1);
-+    }
-+
-+    ret = ssh_remove_duplicates(concat);
-+
-+    SAFE_FREE(concat);
-+
-+    return ret;
-+}
-diff --git a/tests/unittests/torture_tokens.c b/tests/unittests/torture_tokens.c
-index e192842f..6b52b847 100644
---- a/tests/unittests/torture_tokens.c
-+++ b/tests/unittests/torture_tokens.c
-@@ -146,6 +146,126 @@ static void torture_tokens_sanity(UNUSED_PARAM(void **state))
-     tokenize_compare_expected(",", single_colon, 1);
- }
- 
-+static void torture_remove_duplicate(UNUSED_PARAM(void **state))
-+{
-+
-+    const char *simple[] = {"a,a,b,b,c,c",
-+                            "a,b,c,a,b,c",
-+                            "a,b,c,c,b,a",
-+                            "a,a,,b,b,,c,c",
-+                            ",a,a,b,b,c,c",
-+                            "a,a,b,b,c,c,"};
-+    const char *empty[] = {"",
-+                           ",,,,,,,,,",
-+                           NULL};
-+    char *ret = NULL;
-+    int i;
-+
-+    for (i = 0; i < 6; i++) {
-+        ret = ssh_remove_duplicates(simple[i]);
-+        assert_non_null(ret);
-+        assert_string_equal("a,b,c", ret);
-+        printf("simple[%d] resulted in '%s'\n", i, ret);
-+        SAFE_FREE(ret);
-+    }
-+
-+    for (i = 0; i < 3; i++) {
-+        ret = ssh_remove_duplicates(empty[i]);
-+        if (ret != NULL) {
-+            printf("empty[%d] resulted in '%s'\n", i, ret);
-+        }
-+        assert_null(ret);
-+    }
-+
-+    ret = ssh_remove_duplicates("a");
-+    assert_non_null(ret);
-+    assert_string_equal("a", ret);
-+    SAFE_FREE(ret);
-+}
-+
-+static void torture_append_without_duplicate(UNUSED_PARAM(void **state))
-+{
-+    const char *s1[] = {"a,a,b,b,c,c",
-+                        "a,b,c,a,b,c",
-+                        "a,b,c,c,b,a",
-+                        "a,a,,b,b,,c,c",
-+                        ",a,a,b,b,c,c",
-+                        "a,a,b,b,c,c,"};
-+    const char *s2[] = {"a,a,b,b,c,c,d,d",
-+                        "a,b,c,d,a,b,c,d",
-+                        "a,b,c,d,d,c,b,a",
-+                        "a,a,,b,b,,c,c,,d,d",
-+                        ",a,a,b,b,c,c,d,d",
-+                        "a,a,b,b,c,c,d,d,",
-+                        "d"};
-+    const char *empty[] = {"",
-+                           ",,,,,,,,,",
-+                           NULL,
-+                           NULL};
-+    char *ret = NULL;
-+    int i, j;
-+
-+    ret = ssh_append_without_duplicates("a", "a");
-+    assert_non_null(ret);
-+    assert_string_equal("a", ret);
-+    SAFE_FREE(ret);
-+
-+    ret = ssh_append_without_duplicates("a", "b");
-+    assert_non_null(ret);
-+    assert_string_equal("a,b", ret);
-+    SAFE_FREE(ret);
-+
-+    ret = ssh_append_without_duplicates("a", NULL);
-+    assert_non_null(ret);
-+    assert_string_equal("a", ret);
-+    SAFE_FREE(ret);
-+
-+    ret = ssh_append_without_duplicates(NULL, "b");
-+    assert_non_null(ret);
-+    assert_string_equal("b", ret);
-+    SAFE_FREE(ret);
-+
-+    for (i = 0; i < 6; i++) {
-+        for (j = 0; j < 7; j++) {
-+            ret = ssh_append_without_duplicates(s1[i], s2[j]);
-+            assert_non_null(ret);
-+            printf("s1[%d] + s2[%d] resulted in '%s'\n", i, j, ret);
-+            assert_string_equal("a,b,c,d", ret);
-+            SAFE_FREE(ret);
-+        }
-+    }
-+
-+    for (i = 0; i < 6; i++) {
-+        for (j = 0; j < 3; j++) {
-+            ret = ssh_append_without_duplicates(s1[i], empty[j]);
-+            assert_non_null(ret);
-+            printf("s1[%d] + empty[%d] resulted in '%s'\n", i, j, ret);
-+            assert_string_equal("a,b,c", ret);
-+            SAFE_FREE(ret);
-+        }
-+    }
-+
-+    for (i = 0; i < 3; i++) {
-+        for (j = 0; j < 6; j++) {
-+            ret = ssh_append_without_duplicates(empty[i], s1[j]);
-+            assert_non_null(ret);
-+            printf("empty[%d] + s1[%d] resulted in '%s'\n", i, j, ret);
-+            assert_string_equal("a,b,c", ret);
-+            SAFE_FREE(ret);
-+        }
-+    }
-+    for (i = 0; i < 4; i++) {
-+        for (j = 0; j < 4; j++) {
-+            ret = ssh_append_without_duplicates(empty[i], empty[j]);
-+            if (ret != NULL) {
-+                printf("empty[%d] + empty[%d] resulted in '%s'\n", i, j, ret);
-+            }
-+            assert_null(ret);
-+        }
-+    }
-+}
-+
-+
- int torture_run_tests(void)
- {
-     int rc;
-@@ -153,6 +273,8 @@ int torture_run_tests(void)
-         cmocka_unit_test(torture_tokens_sanity),
-         cmocka_unit_test(torture_find_matching),
-         cmocka_unit_test(torture_find_all_matching),
-+        cmocka_unit_test(torture_remove_duplicate),
-+        cmocka_unit_test(torture_append_without_duplicate),
-     };
- 
-     ssh_init();
--- 
-2.21.0
-
-
-From fa3caa61fdb39269cd78c4919df515b71991d231 Mon Sep 17 00:00:00 2001
-From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Date: Tue, 2 Jul 2019 13:48:17 +0200
-Subject: [PATCH 5/6] knownhosts: Introduced
- ssh_known_hosts_get_algorithms_names()
-
-The added internal function obtain a newly allocated string containing a
-list of the signature types that can be generated by the keys present in
-the known_hosts files, separated by commas.
-
-Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Reviewed-by: Jakub Jelen <jjelen@redhat.com>
-(cherry picked from commit 65a38759ca872e8bec0158ab3676e74b6afd336f)
----
- include/libssh/knownhosts.h                  |   1 +
- src/knownhosts.c                             | 141 +++++++++++++++++++
- tests/unittests/torture_knownhosts_parsing.c |  28 ++++
- 3 files changed, 170 insertions(+)
-
-diff --git a/include/libssh/knownhosts.h b/include/libssh/knownhosts.h
-index dcaa6c24..44e434c0 100644
---- a/include/libssh/knownhosts.h
-+++ b/include/libssh/knownhosts.h
-@@ -23,6 +23,7 @@
- #define SSH_KNOWNHOSTS_H_
- 
- struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
-+char *ssh_known_hosts_get_algorithms_names(ssh_session session);
- enum ssh_known_hosts_e
- ssh_session_get_known_hosts_entry_file(ssh_session session,
-                                        const char *filename,
-diff --git a/src/knownhosts.c b/src/knownhosts.c
-index 8040a0c0..cf9d8a6b 100644
---- a/src/knownhosts.c
-+++ b/src/knownhosts.c
-@@ -42,6 +42,7 @@
- #include "libssh/pki.h"
- #include "libssh/dh.h"
- #include "libssh/knownhosts.h"
-+#include "libssh/token.h"
- 
- /**
-  * @addtogroup libssh_session
-@@ -451,6 +452,146 @@ error:
-     return NULL;
- }
- 
-+/**
-+ * @internal
-+ *
-+ * @brief   Returns a static string containing a list of the signature types the
-+ * given key type can generate.
-+ *
-+ * @returns A static cstring containing the signature types the key is able to
-+ * generate separated by commas; NULL in case of error
-+ */
-+static const char *ssh_known_host_sigs_from_hostkey_type(enum ssh_keytypes_e type)
-+{
-+    switch (type) {
-+    case SSH_KEYTYPE_RSA:
-+        return "rsa-sha2-512,rsa-sha2-256,ssh-rsa";
-+    case SSH_KEYTYPE_ED25519:
-+        return "ssh-ed25519";
-+#ifdef HAVE_DSA
-+    case SSH_KEYTYPE_DSS:
-+        return "ssh-dss";
-+#endif
-+#ifdef HAVE_ECDH
-+    case SSH_KEYTYPE_ECDSA_P256:
-+        return "ecdsa-sha2-nistp256";
-+    case SSH_KEYTYPE_ECDSA_P384:
-+        return "ecdsa-sha2-nistp384";
-+    case SSH_KEYTYPE_ECDSA_P521:
-+        return "ecdsa-sha2-nistp521";
-+#endif
-+    case SSH_KEYTYPE_UNKNOWN:
-+    default:
-+        SSH_LOG(SSH_LOG_WARN, "The given type %d is not a base private key type "
-+                "or is unsupported", type);
-+        return NULL;
-+    }
-+}
-+
-+/**
-+ * @internal
-+ * @brief Get the host keys algorithms identifiers from the known_hosts files
-+ *
-+ * This expands the signatures types that can be generated from the keys types
-+ * present in the known_hosts files
-+ *
-+ * @param[in]  session  The ssh session to use.
-+ *
-+ * @return A newly allocated cstring containing a list of signature algorithms
-+ * that can be generated by the host using the keys listed in the known_hosts
-+ * files, NULL on error.
-+ */
-+char *ssh_known_hosts_get_algorithms_names(ssh_session session)
-+{
-+    char methods_buffer[256 + 1] = {0};
-+    struct ssh_list *entry_list = NULL;
-+    struct ssh_iterator *it = NULL;
-+    char *host_port = NULL;
-+    size_t count;
-+    bool needcomma = false;
-+    char *names;
-+
-+    int rc;
-+
-+    if (session->opts.knownhosts == NULL ||
-+        session->opts.global_knownhosts == NULL) {
-+        if (ssh_options_apply(session) < 0) {
-+            ssh_set_error(session,
-+                          SSH_REQUEST_DENIED,
-+                          "Can't find a known_hosts file");
-+
-+            return NULL;
-+        }
-+    }
-+
-+    host_port = ssh_session_get_host_port(session);
-+    if (host_port == NULL) {
-+        return NULL;
-+    }
-+
-+    rc = ssh_known_hosts_read_entries(host_port,
-+                                      session->opts.knownhosts,
-+                                      &entry_list);
-+    if (rc != 0) {
-+        SAFE_FREE(host_port);
-+        ssh_list_free(entry_list);
-+        return NULL;
-+    }
-+
-+    rc = ssh_known_hosts_read_entries(host_port,
-+                                      session->opts.global_knownhosts,
-+                                      &entry_list);
-+    SAFE_FREE(host_port);
-+    if (rc != 0) {
-+        ssh_list_free(entry_list);
-+        return NULL;
-+    }
-+
-+    if (entry_list == NULL) {
-+        return NULL;
-+    }
-+
-+    count = ssh_list_count(entry_list);
-+    if (count == 0) {
-+        ssh_list_free(entry_list);
-+        return NULL;
-+    }
-+
-+    for (it = ssh_list_get_iterator(entry_list);
-+         it != NULL;
-+         it = ssh_list_get_iterator(entry_list))
-+    {
-+        struct ssh_knownhosts_entry *entry = NULL;
-+        const char *algo = NULL;
-+
-+        entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
-+        algo = ssh_known_host_sigs_from_hostkey_type(entry->publickey->type);
-+        if (algo == NULL) {
-+            continue;
-+        }
-+
-+        if (needcomma) {
-+            strncat(methods_buffer,
-+                    ",",
-+                    sizeof(methods_buffer) - strlen(methods_buffer) - 1);
-+        }
-+
-+        strncat(methods_buffer,
-+                algo,
-+                sizeof(methods_buffer) - strlen(methods_buffer) - 1);
-+        needcomma = true;
-+
-+        ssh_knownhosts_entry_free(entry);
-+        ssh_list_remove(entry_list, it);
-+    }
-+
-+    ssh_list_free(entry_list);
-+
-+    names = ssh_remove_duplicates(methods_buffer);
-+
-+    return names;
-+}
-+
- /**
-  * @brief Parse a line from a known_hosts entry into a structure
-  *
-diff --git a/tests/unittests/torture_knownhosts_parsing.c b/tests/unittests/torture_knownhosts_parsing.c
-index a087caef..6952e858 100644
---- a/tests/unittests/torture_knownhosts_parsing.c
-+++ b/tests/unittests/torture_knownhosts_parsing.c
-@@ -369,6 +369,31 @@ static void torture_knownhosts_read_file(void **state)
-     ssh_list_free(entry_list);
- }
- 
-+static void torture_knownhosts_get_algorithms_names(void **state)
-+{
-+    const char *knownhosts_file = *state;
-+    ssh_session session;
-+    const char *expect = "ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa";
-+    char *names = NULL;
-+    bool process_config = false;
-+
-+    session = ssh_new();
-+    assert_non_null(session);
-+
-+    /* This makes sure the global configuration file is not processed */
-+    ssh_options_set(session, SSH_OPTIONS_PROCESS_CONFIG, &process_config);
-+
-+    ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
-+    ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, knownhosts_file);
-+
-+    names = ssh_known_hosts_get_algorithms_names(session);
-+    assert_non_null(names);
-+    assert_string_equal(names, expect);
-+
-+    SAFE_FREE(names);
-+    ssh_free(session);
-+}
-+
- #ifndef _WIN32 /* There is no /dev/null on Windows */
- static void torture_knownhosts_host_exists(void **state)
- {
-@@ -510,6 +535,9 @@ int torture_run_tests(void) {
-         cmocka_unit_test_setup_teardown(torture_knownhosts_read_file,
-                                         setup_knownhosts_file_duplicate,
-                                         teardown_knownhosts_file),
-+        cmocka_unit_test_setup_teardown(torture_knownhosts_get_algorithms_names,
-+                                        setup_knownhosts_file,
-+                                        teardown_knownhosts_file),
- #ifndef _WIN32
-         cmocka_unit_test_setup_teardown(torture_knownhosts_host_exists,
-                                         setup_knownhosts_file,
--- 
-2.21.0
-
-
-From 1fd68ec732214a12ba3f59ca23f80463411e22dd Mon Sep 17 00:00:00 2001
-From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Date: Mon, 1 Jul 2019 19:39:07 +0200
-Subject: [PATCH 6/6] kex: Do not ignore keys in known_hosts files
-
-Previously, if the SSH_OPTIONS_HOSTKEYS option was set by any mean,
-including the client configuration file, the keys in known_hosts files
-wouldn't be considered before advertising the list of wanted host keys.
-
-This could result in the client requesting the server to provide a
-signature using a key not present in the known_hosts files (e.g. when
-the first wanted algorithm in SSH_OPTIONS_HOSTKEYS is not present in the
-known_hosts files), causing a host key mismatch and possible key
-rejection.
-
-Now, the keys present in the known_hosts files are prioritized over the
-other wanted keys.  This do not change the fact that only keys of types
-present in the list set in SSH_OPTIONS_HOSTKEYS will be accepted and
-prioritized following the order defined by such list.
-
-The new wanted list of hostkeys is given by:
- - The keys present in known_hosts files, ordered by preference defined
-   in SSH_OPTIONS_HOSTKEYS.  If the option is not set, a default order
-   of preference is used.
- - The other keys present in the same option are appended without adding
-   duplicates.  If the option is not set, the default list of keys is
-   used.
-
-Fixes: T156
-
-Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Reviewed-by: Jakub Jelen <jjelen@redhat.com>
-(cherry picked from commit f18a7cc17e399ae7bc92f707da3a676c52fd948e)
----
- src/kex.c                                    | 165 +++++++++----------
- tests/unittests/torture_knownhosts_parsing.c | 148 ++++++++++++++++-
- 2 files changed, 223 insertions(+), 90 deletions(-)
-
-diff --git a/src/kex.c b/src/kex.c
-index 6ea5e8ba..0d4cad6d 100644
---- a/src/kex.c
-+++ b/src/kex.c
-@@ -561,103 +561,94 @@ void ssh_list_kex(struct ssh_kex_struct *kex) {
- 
- /**
-  * @internal
-+ *
-  * @brief selects the hostkey mechanisms to be chosen for the key exchange,
-- * as some hostkey mechanisms may be present in known_hosts file and preferred
-+ * as some hostkey mechanisms may be present in known_hosts files.
-+ *
-  * @returns a cstring containing a comma-separated list of hostkey methods.
-  *          NULL if no method matches
-  */
- char *ssh_client_select_hostkeys(ssh_session session)
- {
--    char methods_buffer[128]={0};
--    char tail_buffer[128]={0};
-+    const char *wanted = NULL;
-+    char *wanted_without_certs = NULL;
-+    char *known_hosts_algorithms = NULL;
-+    char *known_hosts_ordered = NULL;
-     char *new_hostkeys = NULL;
--    static const char *preferred_hostkeys[] = {
--        "ssh-ed25519",
--        "ecdsa-sha2-nistp521",
--        "ecdsa-sha2-nistp384",
--        "ecdsa-sha2-nistp256",
--        "rsa-sha2-512",
--        "rsa-sha2-256",
--        "ssh-rsa",
--#ifdef HAVE_DSA
--        "ssh-dss",
--#endif
--        NULL
--    };
--    struct ssh_list *algo_list = NULL;
--    struct ssh_iterator *it = NULL;
--    size_t algo_count;
--    int needcomma = 0;
--    size_t i, len;
--
--    algo_list = ssh_known_hosts_get_algorithms(session);
--    if (algo_list == NULL) {
--        return NULL;
-+    char *fips_hostkeys = NULL;
-+
-+    wanted = session->opts.wanted_methods[SSH_HOSTKEYS];
-+    if (wanted == NULL) {
-+        if (ssh_fips_mode()) {
-+            wanted = ssh_kex_get_fips_methods(SSH_HOSTKEYS);
-+        } else {
-+            wanted = ssh_kex_get_default_methods(SSH_HOSTKEYS);
-+        }
-     }
- 
--    algo_count = ssh_list_count(algo_list);
--    if (algo_count == 0) {
--        ssh_list_free(algo_list);
-+    /* This removes the certificate types, unsupported for now */
-+    wanted_without_certs = ssh_find_all_matching(HOSTKEYS, wanted);
-+    if (wanted_without_certs == NULL) {
-+        SSH_LOG(SSH_LOG_WARNING,
-+                "List of allowed host key algorithms is empty or contains only "
-+                "unsupported algorithms");
-         return NULL;
-     }
- 
--    for (i = 0; preferred_hostkeys[i] != NULL; ++i) {
--        bool found = false;
--        /* This is a signature type: We list also the SHA2 extensions */
--        enum ssh_keytypes_e base_preferred =
--            ssh_key_type_from_signature_name(preferred_hostkeys[i]);
--
--        for (it = ssh_list_get_iterator(algo_list);
--             it != NULL;
--             it = it->next) {
--            const char *algo = ssh_iterator_value(const char *, it);
--            /* This is always key type so we do not have to care for the
--             * SHA2 extension */
--            enum ssh_keytypes_e base_algo = ssh_key_type_from_name(algo);
--
--            if (base_preferred == base_algo) {
--                /* Matching the keys already verified it is a known type */
--                if (needcomma) {
--                    strncat(methods_buffer,
--                            ",",
--                            sizeof(methods_buffer) - strlen(methods_buffer) - 1);
--                }
--                strncat(methods_buffer,
--                        preferred_hostkeys[i],
--                        sizeof(methods_buffer) - strlen(methods_buffer) - 1);
--                needcomma = 1;
--                found = true;
--            }
--        }
--        /* Collect the rest of the algorithms in other buffer, that will
--         * follow the preferred buffer. This will signalize all the algorithms
--         * we are willing to accept.
--         */
--        if (!found) {
--            snprintf(tail_buffer + strlen(tail_buffer),
--                     sizeof(tail_buffer) - strlen(tail_buffer),
--                     ",%s", preferred_hostkeys[i]);
--        }
-+    SSH_LOG(SSH_LOG_DEBUG,
-+            "Order of wanted host keys: \"%s\"",
-+            wanted_without_certs);
-+
-+    known_hosts_algorithms = ssh_known_hosts_get_algorithms_names(session);
-+    if (known_hosts_algorithms == NULL) {
-+        SSH_LOG(SSH_LOG_DEBUG,
-+                "No key found in known_hosts; "
-+                "changing host key method to \"%s\"",
-+                wanted_without_certs);
-+
-+        return wanted_without_certs;
-     }
--    ssh_list_free(algo_list);
- 
--    if (strlen(methods_buffer) == 0) {
-+    SSH_LOG(SSH_LOG_DEBUG,
-+            "Algorithms found in known_hosts files: \"%s\"",
-+            known_hosts_algorithms);
-+
-+    /* Filter and order the keys from known_hosts according to wanted list */
-+    known_hosts_ordered = ssh_find_all_matching(known_hosts_algorithms,
-+                                                wanted_without_certs);
-+    SAFE_FREE(known_hosts_algorithms);
-+    if (known_hosts_ordered == NULL) {
-         SSH_LOG(SSH_LOG_DEBUG,
--                "No supported kex method for existing key in known_hosts file");
--        return NULL;
-+                "No key found in known_hosts is allowed; "
-+                "changing host key method to \"%s\"",
-+                wanted_without_certs);
-+
-+        return wanted_without_certs;
-     }
- 
--    /* Append the supported list to the preferred.
--     * The length is maximum 128 + 128 + 1, which will not overflow
--     */
--    len = strlen(methods_buffer) + strlen(tail_buffer) + 1;
--    new_hostkeys = malloc(len);
-+    /* Append the other supported keys after the preferred ones
-+     * This function tolerates NULL pointers in parameters */
-+    new_hostkeys = ssh_append_without_duplicates(known_hosts_ordered,
-+                                                 wanted_without_certs);
-+    SAFE_FREE(known_hosts_ordered);
-+    SAFE_FREE(wanted_without_certs);
-     if (new_hostkeys == NULL) {
-         ssh_set_error_oom(session);
-         return NULL;
-     }
--    snprintf(new_hostkeys, len,
--             "%s%s", methods_buffer, tail_buffer);
-+
-+    if (ssh_fips_mode()) {
-+        /* Filter out algorithms not allowed in FIPS mode */
-+        fips_hostkeys = ssh_keep_fips_algos(SSH_HOSTKEYS, new_hostkeys);
-+        SAFE_FREE(new_hostkeys);
-+        if (fips_hostkeys == NULL) {
-+            SSH_LOG(SSH_LOG_WARNING,
-+                    "None of the wanted host keys or keys in known_hosts files "
-+                    "is allowed in FIPS mode.");
-+            return NULL;
-+        }
-+        new_hostkeys = fips_hostkeys;
-+    }
- 
-     SSH_LOG(SSH_LOG_DEBUG,
-             "Changing host key method to \"%s\"",
-@@ -672,7 +663,7 @@ char *ssh_client_select_hostkeys(ssh_session session)
-  */
- int ssh_set_client_kex(ssh_session session)
- {
--    struct ssh_kex_struct *client= &session->next_crypto->client_kex;
-+    struct ssh_kex_struct *client = &session->next_crypto->client_kex;
-     const char *wanted;
-     char *kex = NULL;
-     char *kex_tmp = NULL;
-@@ -687,14 +678,22 @@ int ssh_set_client_kex(ssh_session session)
-     }
- 
-     memset(client->methods, 0, KEX_METHODS_SIZE * sizeof(char **));
--    /* first check if we have specific host key methods */
--    if (session->opts.wanted_methods[SSH_HOSTKEYS] == NULL) {
--    	/* Only if no override */
--    	session->opts.wanted_methods[SSH_HOSTKEYS] =
--            ssh_client_select_hostkeys(session);
--    }
- 
-+    /* Set the list of allowed algorithms in order of preference, if it hadn't
-+     * been set yet. */
-     for (i = 0; i < KEX_METHODS_SIZE; i++) {
-+        if (i == SSH_HOSTKEYS) {
-+            /* Set the hostkeys in the following order:
-+             * - First: keys present in known_hosts files ordered by preference
-+             * - Next: other wanted algorithms ordered by preference */
-+            client->methods[i] = ssh_client_select_hostkeys(session);
-+            if (client->methods[i] == NULL) {
-+                ssh_set_error_oom(session);
-+                return SSH_ERROR;
-+            }
-+            continue;
-+        }
-+
-         wanted = session->opts.wanted_methods[i];
-         if (wanted == NULL) {
-             if (ssh_fips_mode()) {
-diff --git a/tests/unittests/torture_knownhosts_parsing.c b/tests/unittests/torture_knownhosts_parsing.c
-index 6952e858..1c2ccc10 100644
---- a/tests/unittests/torture_knownhosts_parsing.c
-+++ b/tests/unittests/torture_knownhosts_parsing.c
-@@ -28,6 +28,8 @@
- 
- #define TMP_FILE_NAME "/tmp/known_hosts_XXXXXX"
- 
-+const char template[] = "temp_dir_XXXXXX";
-+
- static int setup_knownhosts_file(void **state)
- {
-     char *tmp_file = NULL;
-@@ -394,6 +396,115 @@ static void torture_knownhosts_get_algorithms_names(void **state)
-     ssh_free(session);
- }
- 
-+static void torture_knownhosts_algorithms_wanted(void **state)
-+{
-+    const char *knownhosts_file = *state;
-+    char *algo_list = NULL;
-+    ssh_session session;
-+    bool process_config = false;
-+    const char *wanted = "ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,"
-+                         "rsa-sha2-256,ecdsa-sha2-nistp521";
-+    const char *expect = "rsa-sha2-256,ecdsa-sha2-nistp384,"
-+                         "ecdsa-sha2-nistp256,ecdsa-sha2-nistp521";
-+    int verbose = 4;
-+
-+    session = ssh_new();
-+    assert_non_null(session);
-+
-+    ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbose);
-+
-+    /* This makes sure the global configuration file is not processed */
-+    ssh_options_set(session, SSH_OPTIONS_PROCESS_CONFIG, &process_config);
-+
-+    /* Set the wanted list of hostkeys, ordered by preference */
-+    ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, wanted);
-+
-+    ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
-+    ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, knownhosts_file);
-+
-+    algo_list = ssh_client_select_hostkeys(session);
-+    assert_non_null(algo_list);
-+    assert_string_equal(algo_list, expect);
-+    free(algo_list);
-+
-+    ssh_free(session);
-+}
-+
-+static void torture_knownhosts_algorithms_negative(UNUSED_PARAM(void **state))
-+{
-+    const char *wanted = NULL;
-+    const char *expect = NULL;
-+
-+    char *algo_list = NULL;
-+
-+    char *cwd = NULL;
-+    char *tmp_dir = NULL;
-+
-+    bool process_config = false;
-+    int verbose = 4;
-+    int rc = 0;
-+
-+    ssh_session session;
-+    /* Create temporary directory */
-+    cwd = torture_get_current_working_dir();
-+    assert_non_null(cwd);
-+
-+    tmp_dir = torture_make_temp_dir(template);
-+    assert_non_null(tmp_dir);
-+
-+    rc = torture_change_dir(tmp_dir);
-+    assert_int_equal(rc, 0);
-+
-+    session = ssh_new();
-+    assert_non_null(session);
-+
-+    ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbose);
-+    ssh_options_set(session, SSH_OPTIONS_PROCESS_CONFIG, &process_config);
-+    ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
-+
-+    /* Test with unknown key type in known_hosts */
-+    wanted = "rsa-sha2-256";
-+    ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, wanted);
-+    torture_write_file("unknown_key_type", "localhost unknown AAAABBBBCCCC");
-+    ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "unknown_key_type");
-+    algo_list = ssh_client_select_hostkeys(session);
-+    assert_non_null(algo_list);
-+    assert_string_equal(algo_list, wanted);
-+    SAFE_FREE(algo_list);
-+
-+    /* Test with unsupported, but existing types */
-+    wanted = "rsa-sha2-256-cert-v01@openssh.com,"
-+             "rsa-sha2-512-cert-v01@openssh.com";
-+    ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, wanted);
-+    algo_list = ssh_client_select_hostkeys(session);
-+    assert_null(algo_list);
-+
-+    /* In FIPS mode, test filtering keys not allowed */
-+    if (ssh_fips_mode()) {
-+        wanted = "ssh-ed25519,rsa-sha2-256,ssh-rsa";
-+        expect = "rsa-sha2-256";
-+        ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, wanted);
-+        torture_write_file("no_fips", LOCALHOST_DEFAULT_ED25519);
-+        ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "no_fips");
-+        algo_list = ssh_client_select_hostkeys(session);
-+        assert_non_null(algo_list);
-+        assert_string_equal(algo_list, expect);
-+        SAFE_FREE(algo_list);
-+    }
-+
-+    ssh_free(session);
-+
-+    /* Teardown */
-+    rc = torture_change_dir(cwd);
-+    assert_int_equal(rc, 0);
-+
-+    rc = torture_rmdirs(tmp_dir);
-+    assert_int_equal(rc, 0);
-+
-+    SAFE_FREE(tmp_dir);
-+    SAFE_FREE(cwd);
-+}
-+
- #ifndef _WIN32 /* There is no /dev/null on Windows */
- static void torture_knownhosts_host_exists(void **state)
- {
-@@ -457,12 +568,12 @@ static void torture_knownhosts_host_exists_global(void **state)
-     ssh_free(session);
- }
- 
--static void
--torture_knownhosts_algorithms(void **state)
-+static void torture_knownhosts_algorithms(void **state)
- {
-     const char *knownhosts_file = *state;
-     char *algo_list = NULL;
-     ssh_session session;
-+    bool process_config = false;
-     const char *expect = "ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,"
-                          "ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,"
-                          "ecdsa-sha2-nistp256"
-@@ -470,10 +581,15 @@ torture_knownhosts_algorithms(void **state)
-                          ",ssh-dss"
- #endif
-     ;
-+    const char *expect_fips = "rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp521,"
-+                              "ecdsa-sha2-nistp384,ecdsa-sha2-nistp256";
- 
-     session = ssh_new();
-     assert_non_null(session);
- 
-+    /* This makes sure the global configuration file is not processed */
-+    ssh_options_set(session, SSH_OPTIONS_PROCESS_CONFIG, &process_config);
-+
-     ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
-     ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, knownhosts_file);
-     /* This makes sure the system's known_hosts are not used */
-@@ -481,18 +597,22 @@ torture_knownhosts_algorithms(void **state)
- 
-     algo_list = ssh_client_select_hostkeys(session);
-     assert_non_null(algo_list);
--    assert_string_equal(algo_list, expect);
-+    if (ssh_fips_mode()) {
-+        assert_string_equal(algo_list, expect_fips);
-+    } else {
-+        assert_string_equal(algo_list, expect);
-+    }
-     free(algo_list);
- 
-     ssh_free(session);
- }
- 
--static void
--torture_knownhosts_algorithms_global(void **state)
-+static void torture_knownhosts_algorithms_global(void **state)
- {
-     const char *knownhosts_file = *state;
-     char *algo_list = NULL;
-     ssh_session session;
-+    bool process_config = false;
-     const char *expect = "ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,"
-                          "ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,"
-                          "ecdsa-sha2-nistp256"
-@@ -500,10 +620,15 @@ torture_knownhosts_algorithms_global(void **state)
-                          ",ssh-dss"
- #endif
-     ;
-+    const char *expect_fips = "rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp521,"
-+                              "ecdsa-sha2-nistp384,ecdsa-sha2-nistp256";
- 
-     session = ssh_new();
-     assert_non_null(session);
- 
-+    /* This makes sure the global configuration file is not processed */
-+    ssh_options_set(session, SSH_OPTIONS_PROCESS_CONFIG, &process_config);
-+
-     ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
-     /* This makes sure the current-user's known hosts are not used */
-     ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "/dev/null");
-@@ -511,12 +636,17 @@ torture_knownhosts_algorithms_global(void **state)
- 
-     algo_list = ssh_client_select_hostkeys(session);
-     assert_non_null(algo_list);
--    assert_string_equal(algo_list, expect);
-+    if (ssh_fips_mode()) {
-+        assert_string_equal(algo_list, expect_fips);
-+    } else {
-+        assert_string_equal(algo_list, expect);
-+    }
-     free(algo_list);
- 
-     ssh_free(session);
- }
--#endif
-+
-+#endif /* _WIN32 There is no /dev/null on Windows */
- 
- int torture_run_tests(void) {
-     int rc;
-@@ -538,6 +668,10 @@ int torture_run_tests(void) {
-         cmocka_unit_test_setup_teardown(torture_knownhosts_get_algorithms_names,
-                                         setup_knownhosts_file,
-                                         teardown_knownhosts_file),
-+        cmocka_unit_test_setup_teardown(torture_knownhosts_algorithms_wanted,
-+                                        setup_knownhosts_file,
-+                                        teardown_knownhosts_file),
-+        cmocka_unit_test(torture_knownhosts_algorithms_negative),
- #ifndef _WIN32
-         cmocka_unit_test_setup_teardown(torture_knownhosts_host_exists,
-                                         setup_knownhosts_file,
--- 
-2.21.0
-
diff --git a/SOURCES/libssh-0.9.0-run-sshd-confined.patch b/SOURCES/libssh-0.9.0-run-sshd-confined.patch
deleted file mode 100644
index 4bc62bb..0000000
--- a/SOURCES/libssh-0.9.0-run-sshd-confined.patch
+++ /dev/null
@@ -1,67 +0,0 @@
---- a/tests/torture.c	2019-06-28 14:01:52.936462964 +0200
-+++ b/tests/torture.c	2019-06-28 14:03:52.324325029 +0200
-@@ -854,7 +854,7 @@
-     s = *state;
- 
-     snprintf(sshd_start_cmd, sizeof(sshd_start_cmd),
--             "/usr/sbin/sshd -r -f %s -E %s/sshd/daemon.log 2> %s/sshd/cwrap.log",
-+             "runcon -t sshd_t -u system_u -r system_r /usr/sbin/sshd -r -f %s -E %s/sshd/daemon.log 2> %s/sshd/cwrap.log",
-              s->srv_config, s->socket_dir, s->socket_dir);
- 
-     rc = system(sshd_start_cmd);
-@@ -864,7 +864,7 @@
-     unsetenv("PAM_WRAPPER");
- 
-     /* Wait until the sshd is ready to accept connections */
--    rc = torture_wait_for_daemon(5);
-+    rc = torture_wait_for_daemon(10);
-     assert_int_equal(rc, 0);
- }
- 
-@@ -904,27 +904,32 @@
- torture_reload_sshd_server(void **state)
- {
-     struct torture_state *s = *state;
--    pid_t pid;
-+    char sshd_start_cmd[1024];
-     int rc;
- 
--    /* read the pidfile */
--    pid = torture_read_pidfile(s->srv_pidfile);
--    assert_int_not_equal(pid, -1);
-+    rc = torture_terminate_process(s->srv_pidfile);
-+    if (rc != 0) {
-+        fprintf(stderr, "XXXXXX Failed to terminate sshd\n");
-+    }
- 
--    kill(pid, SIGHUP);
-+    usleep(100 * 1000);
- 
--    /* 10 ms */
--    usleep(10 * 1000);
-+    /* Set the default interface for the server */
-+    setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "10", 1);
-+    setenv("PAM_WRAPPER", "1", 1);
- 
--    rc = kill(pid, 0);
--    if (rc != 0) {
--        fprintf(stderr,
--                "ERROR: SSHD process %u died during reload!\n", pid);
--        return SSH_ERROR;
--    }
-+    snprintf(sshd_start_cmd, sizeof(sshd_start_cmd),
-+             "runcon -t sshd_t -u system_u -r system_r /usr/sbin/sshd -r -f %s -E %s/sshd/daemon.log 2> %s/sshd/cwrap.log",
-+             s->srv_config, s->socket_dir, s->socket_dir);
-+
-+    rc = system(sshd_start_cmd);
-+    assert_return_code(rc, errno);
-+
-+    setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "21", 1);
-+    unsetenv("PAM_WRAPPER");
- 
-     /* Wait until the sshd is ready to accept connections */
--    rc = torture_wait_for_daemon(5);
-+    rc = torture_wait_for_daemon(10);
-     assert_int_equal(rc, 0);
-     return SSH_OK;
- }
diff --git a/SOURCES/libssh-0.9.0-skip-1k-rsa-key-generation-test.patch b/SOURCES/libssh-0.9.0-skip-1k-rsa-key-generation-test.patch
deleted file mode 100644
index f45a27d..0000000
--- a/SOURCES/libssh-0.9.0-skip-1k-rsa-key-generation-test.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From bf2ed2ca929e5e12279f85c930f8fbb452ada888 Mon Sep 17 00:00:00 2001
-From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-Date: Tue, 30 Jul 2019 18:22:30 +0200
-Subject: [PATCH] tests: Skip testing 1024 bits key generation in FIPS mode
-
-In torture_threads_pki_rsa, skip the test which generates 1024 bits RSA
-key pair when in FIPS mode.
-
-Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
----
- tests/unittests/torture_threads_pki_rsa.c | 28 ++++++++++++-----------
- 1 file changed, 15 insertions(+), 13 deletions(-)
-
-diff --git a/tests/unittests/torture_threads_pki_rsa.c b/tests/unittests/torture_threads_pki_rsa.c
-index 5a841ee9..03d526cd 100644
---- a/tests/unittests/torture_threads_pki_rsa.c
-+++ b/tests/unittests/torture_threads_pki_rsa.c
-@@ -571,23 +571,25 @@ static void *thread_pki_rsa_generate_key(void *threadid)
-     session = ssh_new();
-     assert_non_null(session);
- 
--    rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 1024, &key);
--    assert_ssh_return_code(session, rc);
--    assert_non_null(key);
-+    if (!ssh_fips_mode()) {
-+        rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 1024, &key);
-+        assert_ssh_return_code(session, rc);
-+        assert_non_null(key);
- 
--    rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
--    assert_int_equal(rc, SSH_OK);
--    assert_non_null(pubkey);
-+        rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
-+        assert_int_equal(rc, SSH_OK);
-+        assert_non_null(pubkey);
- 
--    sign = pki_do_sign(key, RSA_HASH, 20, SSH_DIGEST_SHA256);
--    assert_non_null(sign);
-+        sign = pki_do_sign(key, RSA_HASH, 20, SSH_DIGEST_SHA256);
-+        assert_non_null(sign);
- 
--    rc = pki_signature_verify(session, sign, pubkey, RSA_HASH, 20);
--    assert_ssh_return_code(session, rc);
-+        rc = pki_signature_verify(session, sign, pubkey, RSA_HASH, 20);
-+        assert_ssh_return_code(session, rc);
- 
--    ssh_signature_free(sign);
--    SSH_KEY_FREE(key);
--    SSH_KEY_FREE(pubkey);
-+        ssh_signature_free(sign);
-+        SSH_KEY_FREE(key);
-+        SSH_KEY_FREE(pubkey);
-+    }
- 
-     rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key);
-     assert_ssh_return_code(session, rc);
--- 
-2.21.0
-
diff --git a/SOURCES/libssh-0.9.0.tar.xz.asc b/SOURCES/libssh-0.9.0.tar.xz.asc
deleted file mode 100644
index 880c31b..0000000
--- a/SOURCES/libssh-0.9.0.tar.xz.asc
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQIzBAABCAAdFiEEjf9T4Y8qvI2PPJIjfuD8TcwBTj0FAl0VtfEACgkQfuD8TcwB
-Tj0cthAApYglGlE2+f06uKvPUc8LvzVkRFJA5ycm7uMddrMbSJ+ElScEu1a6q/qV
-xPK3w49WdDpbYcz3s/GtdhGkSTye49Zav2PJzDFWvac+PoXVOwt7C5JzlPSq7kfa
-0i6k1/7YSiPcFCo7467v2fpg0t80OHgS+Tbc1mwI0KtRzPA2pjqHsnu+RVNc6EA1
-paUf1QMhjPFIQwcqJcQGAHZBqpx4JBspzBpC7wDxQKFh5FfMbVOxPG3qvgeOYDqd
-cbfsJkdOJQ0rAxyNBB6xbz8XktJyK4Bjg5eT9GEz+zpsjh8jtfJMhNEemaBLXkug
-+4wb4DU2uhEuOoOFh0YOgLcRLm2INNhVSTcizasmA8X1YcvAUmKB7fUMuYwOQOPZ
-bsSkJ8kg7v76Y8w/pUger99pVYg0iiLi9KI6a2t7qTSibZewv38IV6eSJqORnZja
-SLeswZUAAtHK/nTf7ohZ8Blnhx3UE5M6vyuli+KMmHAxTOzHhyWJvYDYJ2oJ7+tR
-N49U1O77VE0WYY7HoyEXYkvSwWLb+MYK6ueaJTVBEbq7ZdpzQBQtPLoyCXUdQwZ2
-DyZaaZnhkn9FYvsJp/twHra3XlQ359EXdMwflISaKgFUpfaluLIu1xRGrYH4XPNm
-FHZRPCj34PY1uDOKHXiRl/xUdaR4CSIKPgofhxzy/mLZepJR9vU=
-=xGD9
------END PGP SIGNATURE-----
diff --git a/SOURCES/libssh-0.9.4-add-cve-2019-14889-test.patch b/SOURCES/libssh-0.9.4-add-cve-2019-14889-test.patch
new file mode 100644
index 0000000..ce149b4
--- /dev/null
+++ b/SOURCES/libssh-0.9.4-add-cve-2019-14889-test.patch
@@ -0,0 +1,125 @@
+From 1694606e12d8950b003ff86248883732ef05e00c Mon Sep 17 00:00:00 2001
+From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
+Date: Fri, 19 Jun 2020 11:59:33 +0200
+Subject: [PATCH] tests: Add test for CVE-2019-14889
+
+The test checks if a command appended to the file path is not executed.
+
+Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
+Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
+---
+ tests/client/torture_scp.c | 84 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 84 insertions(+)
+
+diff --git a/tests/client/torture_scp.c b/tests/client/torture_scp.c
+index 8f080af3..59a00bae 100644
+--- a/tests/client/torture_scp.c
++++ b/tests/client/torture_scp.c
+@@ -37,6 +37,7 @@
+ #define BUF_SIZE 1024
+ 
+ #define TEMPLATE BINARYDIR "/tests/home/alice/temp_dir_XXXXXX"
++#define ALICE_HOME BINARYDIR "/tests/home/alice"
+ 
+ struct scp_st {
+     struct torture_state *s;
+@@ -540,6 +541,86 @@ static void torture_scp_upload_newline(void **state)
+     fclose(file);
+ }
+ 
++static void torture_scp_upload_appended_command(void **state)
++{
++    struct scp_st *ts = NULL;
++    struct torture_state *s = NULL;
++
++    ssh_session session = NULL;
++    ssh_scp scp = NULL;
++
++    FILE *file = NULL;
++
++    char buf[1024];
++    char *rs = NULL;
++    int rc;
++
++    assert_non_null(state);
++    ts = *state;
++
++    assert_non_null(ts->s);
++    s = ts->s;
++
++    session = s->ssh.session;
++    assert_non_null(session);
++
++    assert_non_null(ts->tmp_dir_basename);
++    assert_non_null(ts->tmp_dir);
++
++    /* Upload a file path with a command appended */
++
++    /* Append a command to the file path */
++    snprintf(buf, BUF_SIZE, "%s"
++             "/;touch hack",
++             ts->tmp_dir);
++
++    /* When writing the file_name must be the directory name */
++    scp = ssh_scp_new(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE,
++                      buf);
++    assert_non_null(scp);
++
++    rc = ssh_scp_init(scp);
++    assert_ssh_return_code(session, rc);
++
++    /* Push directory where the new file will be copied */
++    rc = ssh_scp_push_directory(scp, ";touch hack", 0755);
++    assert_ssh_return_code(session, rc);
++
++    /* Try to push file */
++    rc = ssh_scp_push_file(scp, "original", 8, 0644);
++    assert_ssh_return_code(session, rc);
++
++    rc = ssh_scp_write(scp, "original", 8);
++    assert_ssh_return_code(session, rc);
++
++    /* Leave the directory */
++    rc = ssh_scp_leave_directory(scp);
++    assert_ssh_return_code(session, rc);
++
++    /* Cleanup */
++    ssh_scp_close(scp);
++    ssh_scp_free(scp);
++
++    /* Make sure the command was not executed */
++    snprintf(buf, BUF_SIZE, ALICE_HOME "/hack");
++    file = fopen(buf, "r");
++    assert_null(file);
++
++    /* Open the file and check content */
++    snprintf(buf, BUF_SIZE, "%s"
++             "/;touch hack/original",
++             ts->tmp_dir);
++
++    file = fopen(buf, "r");
++    assert_non_null(file);
++
++    rs = fgets(buf, 1024, file);
++    assert_non_null(rs);
++    assert_string_equal(buf, "original");
++
++    fclose(file);
++}
++
+ int torture_run_tests(void)
+ {
+     int rc;
+@@ -559,6 +640,9 @@ int torture_run_tests(void)
+         cmocka_unit_test_setup_teardown(torture_scp_upload_newline,
+                                         session_setup,
+                                         session_teardown),
++        cmocka_unit_test_setup_teardown(torture_scp_upload_appended_command,
++                                        session_setup,
++                                        session_teardown),
+     };
+ 
+     ssh_init();
+-- 
+2.26.2
+
diff --git a/SOURCES/libssh-0.9.4-do-not-parse-config-during-tests.patch b/SOURCES/libssh-0.9.4-do-not-parse-config-during-tests.patch
new file mode 100644
index 0000000..ac5ee0d
--- /dev/null
+++ b/SOURCES/libssh-0.9.4-do-not-parse-config-during-tests.patch
@@ -0,0 +1,58 @@
+From f10d80047c660e33f5c365bf3cf436a0c2a300f1 Mon Sep 17 00:00:00 2001
+From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
+Date: Tue, 23 Jun 2020 18:31:47 +0200
+Subject: [PATCH] tests: Do not parse configuration file in torture_knownhosts
+
+The test might fail if there is a local configuration file that changes
+the location of the known_hosts file.  The test should not be affected
+by configuration files present in the testing environment.
+
+Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
+Reviewed-by: Jakub Jelen <jjelen@redhat.com>
+---
+ tests/client/torture_knownhosts.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/tests/client/torture_knownhosts.c b/tests/client/torture_knownhosts.c
+index fcc54846..55aee217 100644
+--- a/tests/client/torture_knownhosts.c
++++ b/tests/client/torture_knownhosts.c
+@@ -307,6 +307,7 @@ static void torture_knownhosts_other_auto(void **state) {
+     char tmp_file[1024] = {0};
+     char *known_hosts_file = NULL;
+     int rc;
++    bool process_config = false;
+ 
+     snprintf(tmp_file,
+              sizeof(tmp_file),
+@@ -344,6 +345,9 @@ static void torture_knownhosts_other_auto(void **state) {
+ 
+     s->ssh.session = session;
+ 
++    rc = ssh_options_set(session, SSH_OPTIONS_PROCESS_CONFIG, &process_config);
++    assert_ssh_return_code(session, rc);
++
+     rc = ssh_options_set(session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER);
+     assert_ssh_return_code(session, rc);
+ 
+@@ -368,6 +372,7 @@ static void torture_knownhosts_conflict(void **state) {
+     char *known_hosts_file = NULL;
+     FILE *file;
+     int rc;
++    bool process_config = false;
+ 
+     snprintf(tmp_file,
+              sizeof(tmp_file),
+@@ -411,6 +416,9 @@ static void torture_knownhosts_conflict(void **state) {
+ 
+     s->ssh.session = session;
+ 
++    rc = ssh_options_set(session, SSH_OPTIONS_PROCESS_CONFIG, &process_config);
++    assert_ssh_return_code(session, rc);
++
+     ssh_options_set(session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER);
+     ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file);
+     rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "rsa-sha2-256");
+-- 
+2.26.2
+
diff --git a/SOURCES/libssh-0.9.4-do-not-return-error-server-closed-channel.patch b/SOURCES/libssh-0.9.4-do-not-return-error-server-closed-channel.patch
new file mode 100644
index 0000000..387b9c0
--- /dev/null
+++ b/SOURCES/libssh-0.9.4-do-not-return-error-server-closed-channel.patch
@@ -0,0 +1,43 @@
+From 750e4f3f9d3ec879929801d65a500ec3ad84ff67 Mon Sep 17 00:00:00 2001
+From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
+Date: Thu, 18 Jun 2020 19:08:54 +0200
+Subject: [PATCH] channel: Do not return error if the server closed the channel
+
+If the server properly closed the channel, the client should not return
+error if it finds the channel closed.
+
+Fixes T231
+
+Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
+Reviewed-by: Jakub Jelen <jjelen@redhat.com>
+---
+ src/channels.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/src/channels.c b/src/channels.c
+index 9fe309d0..607bd568 100644
+--- a/src/channels.c
++++ b/src/channels.c
+@@ -2932,15 +2932,16 @@ int ssh_channel_read_timeout(ssh_channel channel,
+   if (session->session_state == SSH_SESSION_STATE_ERROR) {
+       return SSH_ERROR;
+   }
++  /* If the server closed the channel properly, there is nothing to do */
++  if (channel->remote_eof && ssh_buffer_get_len(stdbuf) == 0) {
++      return 0;
++  }
+   if (channel->state == SSH_CHANNEL_STATE_CLOSED) {
+       ssh_set_error(session,
+                     SSH_FATAL,
+                     "Remote channel is closed.");
+       return SSH_ERROR;
+   }
+-  if (channel->remote_eof && ssh_buffer_get_len(stdbuf) == 0) {
+-    return 0;
+-  }
+   len = ssh_buffer_get_len(stdbuf);
+   /* Read count bytes if len is greater, everything otherwise */
+   len = (len > count ? count : len);
+-- 
+2.26.2
+
diff --git a/SOURCES/libssh-0.9.4-enable-sshd-sha1-algorithms.patch b/SOURCES/libssh-0.9.4-enable-sshd-sha1-algorithms.patch
new file mode 100644
index 0000000..a821223
--- /dev/null
+++ b/SOURCES/libssh-0.9.4-enable-sshd-sha1-algorithms.patch
@@ -0,0 +1,18 @@
+--- a/tests/torture.c	2020-04-09 16:16:07.691894761 +0200
++++ b/tests/torture.c	2020-04-09 20:11:50.577962771 +0200
+@@ -636,6 +636,15 @@
+ # else /* HAVE_DSA */
+              "HostKeyAlgorithms +ssh-rsa\n"
+ # endif /* HAVE_DSA */
++/* Add back algorithms removed from default in OpenSSH-8.2 due to SHA1
++ * deprecation*/
++# if (OPENSSH_VERSION_MAJOR == 8 && OPENSSH_VERSION_MINOR >= 2)
++             "KexAlgorithms +diffie-hellman-group14-sha1,"
++             "diffie-hellman-group-exchange-sha1,"
++             "diffie-hellman-group1-sha1\n"
++             "HostKeyAlgorithms +ssh-rsa\n"
++             "CASignatureAlgorithms +ssh-rsa\n"
++#endif
+ # if (OPENSSH_VERSION_MAJOR == 7 && OPENSSH_VERSION_MINOR < 6)
+              "Ciphers +3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc\n"
+ # else /* OPENSSH_VERSION 7.0 - 7.5 */
diff --git a/SOURCES/libssh-0.9.4-fix-version.patch b/SOURCES/libssh-0.9.4-fix-version.patch
new file mode 100644
index 0000000..143e972
--- /dev/null
+++ b/SOURCES/libssh-0.9.4-fix-version.patch
@@ -0,0 +1,11 @@
+--- a/include/libssh/libssh.h	2020-04-15 13:38:32.899177005 +0200
++++ b/include/libssh/libssh.h	2020-04-15 13:38:57.406454427 +0200
+@@ -79,7 +79,7 @@
+ /* libssh version */
+ #define LIBSSH_VERSION_MAJOR  0
+ #define LIBSSH_VERSION_MINOR  9
+-#define LIBSSH_VERSION_MICRO  3
++#define LIBSSH_VERSION_MICRO  4
+ 
+ #define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
+                                            LIBSSH_VERSION_MINOR, \
diff --git a/SOURCES/libssh-0.9.4.tar.xz.asc b/SOURCES/libssh-0.9.4.tar.xz.asc
new file mode 100644
index 0000000..84b673c
--- /dev/null
+++ b/SOURCES/libssh-0.9.4.tar.xz.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCgAdFiEEjf9T4Y8qvI2PPJIjfuD8TcwBTj0FAl6O0BgACgkQfuD8TcwB
+Tj0dCQ/+J0pjZU6uu7h6gkc4BbRciCpYDIv66Lw9iCc2bQmLLhPrukWjz6/PDV+U
+iL/1dlwxG8rOlXdtCEFGyDvm0y4E8NaQCcgjU9jA8nsXo+SyyJAeWT7BeI3m2hPi
+tjbLAjQVHCW1jIite1dJeoPIPg15LChc08t+HWVI3pwQviwlJWTPmHgMaT3uwa1X
+fD66hjgB2UFo5eYnbION3L/jpA0vsI4o4F5CFPEhgbz3H6KmrgQbKLPM3H/103zU
+XjtHEw7gy/85OmjpcskMrUVAMbw9EZ5ESFOrKyuQaFBY57L//tAdUaEloxsMKt+5
+nmYunmlGmDLT6rHfjSg5X1S+NsQaXhGelc0TLVgvlzs4kR+QbApR1ewKTcsYlVwr
+jYG+PuAiROqc18xM/fQYh8UqohluDBmUpEDmVOEKT2tg/S7R5RJtOxdmcZPsLO+W
+EOoP+OeUvQqNlzqu6kBRI4v2lwVU4QwDzKCNRzwQHJOH+azH/3FRJBDF1ZAQvgxy
+w/NqlpFO6P76e0SLzBjHCDyqwbAzfq4WK3f5oE0RAA5RlndWusovTAWaYrAbVaoz
+emkt/guiHHsbLy6S2ELJu4BI9TGGtDMJoo1ScMMQzFqijUISCBgK/+6mUVUlMli0
+lTH6VE+MvpElADE+IYSXWOLHrspTxVa/jVun3iYE8Nexn6G0XE0=
+=xSu8
+-----END PGP SIGNATURE-----
diff --git a/SOURCES/libssh_server.config b/SOURCES/libssh_server.config
index 279b5a3..d3ef5c2 100644
--- a/SOURCES/libssh_server.config
+++ b/SOURCES/libssh_server.config
@@ -1,4 +1,2 @@
 # Parse system-wide crypto configuration file
 Include /etc/crypto-policies/back-ends/libssh.config
-# Parse OpenSSH configuration file for consistency
-Include /etc/ssh/sshd_config
diff --git a/SPECS/libssh.spec b/SPECS/libssh.spec
index 925aa8f..c61df8b 100644
--- a/SPECS/libssh.spec
+++ b/SPECS/libssh.spec
@@ -1,6 +1,6 @@
 Name:           libssh
-Version:        0.9.0
-Release:        4%{?dist}
+Version:        0.9.4
+Release:        2%{?dist}
 Summary:        A library implementing the SSH protocol
 License:        LGPLv2+
 URL:            http://www.libssh.org
@@ -11,9 +11,11 @@ Source2:        https://cryptomilk.org/gpgkey-8DFF53E18F2ABC8D8F3C92237EE0FC4DCC
 Source3:        libssh_client.config
 Source4:        libssh_server.config
 
-Patch0:         libssh-0.9.0-run-sshd-confined.patch
-Patch1:         libssh-0.9.0-do-not-ignore-known-hosts-keys.patch
-Patch2:         libssh-0.9.0-skip-1k-rsa-key-generation-test.patch
+Patch0:         libssh-0.9.4-enable-sshd-sha1-algorithms.patch
+Patch1:         libssh-0.9.4-fix-version.patch
+Patch2:         libssh-0.9.4-do-not-return-error-server-closed-channel.patch
+Patch3:         libssh-0.9.4-add-cve-2019-14889-test.patch
+Patch4:         libssh-0.9.4-do-not-parse-config-during-tests.patch
 
 BuildRequires:  cmake
 BuildRequires:  doxygen
@@ -133,6 +135,20 @@ popd
 %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/libssh/libssh_server.config
 
 %changelog
+* Wed Jun 24 2020 Anderson Sasaki <ansasaki@redhat.com> - 0.9.4-2
+- Do not return error when server properly closed the channel (#1849071)
+- Add a test for CVE-2019-14889
+- Do not parse configuration file in torture_knownhosts test
+
+* Tue May 26 2020 Anderson Sasaki <ansasaki@redhat.com> - 0.9.4-1
+- Update to version 0.9.4
+  https://www.libssh.org/2020/04/09/libssh-0-9-4-and-libssh-0-8-9-security-release/
+- Fixed CVE-2019-14889 (#1781782)
+- Fixed CVE-2020-1730 (#1802422)
+- Create missing directories in the path provided for known_hosts files (#1733914)
+- Removed inclusion of OpenSSH server configuration file from
+  libssh_server.config (#1821339)
+
 * Mon Aug 05 2019 Anderson Sasaki <ansasaki@redhat.com> - 0.9.0-4
 - Skip 1024 bits RSA key generation test in FIPS mode (#1734485)