diff --git a/libssh.spec b/libssh.spec index 3ba9767..2bb103c 100644 --- a/libssh.spec +++ b/libssh.spec @@ -1,6 +1,6 @@ Name: libssh Version: 0.10.4 -Release: 3%{?dist} +Release: 4%{?dist} Summary: A library implementing the SSH protocol License: LGPLv2+ URL: http://www.libssh.org @@ -41,6 +41,10 @@ Provides: libssh_threads.so.4 Patch1: coverity_scan.patch Patch2: pkcs11_test_fix.patch +Patch3: loglevel.patch +Patch4: plus_sign.patch +Patch5: memory_leak.patch +Patch6: options_apply.patch %description The ssh library was designed to be used by programmers needing a working SSH @@ -133,6 +137,13 @@ popd %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/libssh/libssh_server.config %changelog +* Wed Nov 30 2022 Norbert Pocs - 0.10.4-4 +- Move loglevel closer to openssh loglevel +- Add openssh config feature of +,-,^ for algorithm lists +- Fix memory leaks of bignum +- Prevent multiple expansion of escape characters +- Resolves: rhbz#2132407, rhbz#2137839, rhbz#2144795, rhbz#2136824 + * Tue Oct 4 2022 Norbert Pocs - 0.10.4-3 - Enable pkcs11 support - Fix broken libsofthsm path on i686 diff --git a/loglevel.patch b/loglevel.patch new file mode 100644 index 0000000..e696b0e --- /dev/null +++ b/loglevel.patch @@ -0,0 +1,4385 @@ +From 2bbc3d6b95cf7205bc6416647903d04da280de79 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Tue, 13 Sep 2022 13:03:59 +0200 +Subject: [PATCH 1/5] (bind_)config.c: Move "info" to SSH_LOG_INFO + +No info log will be printed out when Loglevel WARN is set, only errors + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +Reviewed-by: Andreas Schneider +--- + src/bind_config.c | 6 +++--- + src/config.c | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/bind_config.c b/src/bind_config.c +index 27c42c95..e8b9729e 100644 +--- a/src/bind_config.c ++++ b/src/bind_config.c +@@ -437,10 +437,10 @@ ssh_bind_config_parse_line(ssh_bind bind, + if (strcasecmp(p, "quiet") == 0) { + value = SSH_LOG_NONE; + } else if (strcasecmp(p, "fatal") == 0 || +- strcasecmp(p, "error")== 0 || +- strcasecmp(p, "info") == 0) { ++ strcasecmp(p, "error")== 0) { + value = SSH_LOG_WARN; +- } else if (strcasecmp(p, "verbose") == 0) { ++ } else if (strcasecmp(p, "verbose") == 0 || ++ strcasecmp(p, "info") == 0) { + value = SSH_LOG_INFO; + } else if (strcasecmp(p, "DEBUG") == 0 || + strcasecmp(p, "DEBUG1") == 0) { +diff --git a/src/config.c b/src/config.c +index 41ba1054..927225ae 100644 +--- a/src/config.c ++++ b/src/config.c +@@ -965,10 +965,10 @@ ssh_config_parse_line(ssh_session session, + if (strcasecmp(p, "quiet") == 0) { + value = SSH_LOG_NONE; + } else if (strcasecmp(p, "fatal") == 0 || +- strcasecmp(p, "error")== 0 || +- strcasecmp(p, "info") == 0) { ++ strcasecmp(p, "error")== 0) { + value = SSH_LOG_WARN; +- } else if (strcasecmp(p, "verbose") == 0) { ++ } else if (strcasecmp(p, "verbose") == 0 || ++ strcasecmp(p, "info") == 0) { + value = SSH_LOG_INFO; + } else if (strcasecmp(p, "DEBUG") == 0 || + strcasecmp(p, "DEBUG1") == 0) { +-- +2.38.1 + + +From e1f4f06c220e3693d1dc6a30682cdd0e30890070 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Thu, 15 Sep 2022 13:04:32 +0200 +Subject: [PATCH 2/5] SSH_LOG_TRACE: Recategorize loglevels + +Do not print out logs when no fatal error happens. +This approach is similiar to openssh, when Error/Fatal does not print +recoverable error logs. +recategorized based on - SSH_LOG_TRACE are debug logs when error happens + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +Reviewed-by: Andreas Schneider +--- + src/agent.c | 12 ++--- + src/auth.c | 8 +-- + src/bind_config.c | 30 +++++------ + src/buffer.c | 6 +-- + src/channels.c | 2 +- + src/client.c | 2 +- + src/config.c | 40 +++++++------- + src/config_parser.c | 2 +- + src/error.c | 4 +- + src/gssapi.c | 8 +-- + src/kex.c | 6 +-- + src/knownhosts.c | 12 ++--- + src/libcrypto.c | 104 ++++++++++++++++++------------------ + src/libgcrypt.c | 60 ++++++++++----------- + src/libmbedcrypto.c | 82 ++++++++++++++-------------- + src/messages.c | 8 +-- + src/misc.c | 8 +-- + src/packet.c | 4 +- + src/pki.c | 88 +++++++++++++++--------------- + src/pki_container_openssh.c | 46 ++++++++-------- + src/pki_crypto.c | 78 +++++++++++++-------------- + src/pki_ed25519_common.c | 4 +- + src/pki_gcrypt.c | 30 +++++------ + src/pki_mbedcrypto.c | 24 ++++----- + src/session.c | 4 +- + src/socket.c | 6 +-- + 26 files changed, 339 insertions(+), 339 deletions(-) + +diff --git a/src/agent.c b/src/agent.c +index 299b4ad1..59963605 100644 +--- a/src/agent.c ++++ b/src/agent.c +@@ -268,12 +268,12 @@ static int agent_talk(struct ssh_session_struct *session, + if (atomicio(session->agent, payload, 4, 0) == 4) { + if (atomicio(session->agent, ssh_buffer_get(request), len, 0) + != len) { +- SSH_LOG(SSH_LOG_WARN, "atomicio sending request failed: %s", +- ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); ++ SSH_LOG(SSH_LOG_TRACE, "atomicio sending request failed: %s", ++ strerror(errno)); + return -1; + } + } else { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "atomicio sending request length failed: %s", + ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); + return -1; +@@ -281,8 +281,8 @@ static int agent_talk(struct ssh_session_struct *session, + + /* wait for response, read the length of the response packet */ + if (atomicio(session->agent, payload, 4, 1) != 4) { +- SSH_LOG(SSH_LOG_WARN, "atomicio read response length failed: %s", +- ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); ++ SSH_LOG(SSH_LOG_TRACE, "atomicio read response length failed: %s", ++ strerror(errno)); + return -1; + } + +@@ -357,7 +357,7 @@ uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session) + type = bswap_32(type); + #endif + +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Answer type: %d, expected answer: %d", + type, SSH2_AGENT_IDENTITIES_ANSWER); + +diff --git a/src/auth.c b/src/auth.c +index aa3aa965..cc8089a1 100644 +--- a/src/auth.c ++++ b/src/auth.c +@@ -72,7 +72,7 @@ static int ssh_userauth_request_service(ssh_session session) + + rc = ssh_service_request(session, "ssh-userauth"); + if ((rc != SSH_OK) && (rc != SSH_AGAIN)) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Failed to request \"ssh-userauth\" service"); + } + +@@ -202,7 +202,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_banner) { + + banner = ssh_buffer_get_ssh_string(packet); + if (banner == NULL) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Invalid SSH_USERAUTH_BANNER packet"); + } else { + SSH_LOG(SSH_LOG_DEBUG, +@@ -1196,7 +1196,7 @@ int ssh_userauth_publickey_auto(ssh_session session, + + rc = ssh_pki_export_pubkey_file(state->pubkey, pubkey_file); + if (rc == SSH_ERROR) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Could not write public key to file: %s", + pubkey_file); + } +@@ -1206,7 +1206,7 @@ int ssh_userauth_publickey_auto(ssh_session session, + if (state->state == SSH_AUTH_AUTO_STATE_KEY_IMPORTED) { + rc = ssh_userauth_try_publickey(session, username, state->pubkey); + if (rc == SSH_AUTH_ERROR) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Public key authentication error for %s", + privkey_file); + ssh_key_free(state->privkey); +diff --git a/src/bind_config.c b/src/bind_config.c +index e8b9729e..a2f2efe4 100644 +--- a/src/bind_config.c ++++ b/src/bind_config.c +@@ -363,7 +363,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + if (p && (*parser_flags & PARSING)) { + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HOSTKEY, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set Hostkey value '%s'", + count, p); + } +@@ -374,7 +374,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + if (p && (*parser_flags & PARSING)) { + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDADDR, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set ListenAddress value '%s'", + count, p); + } +@@ -385,7 +385,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + if (p && (*parser_flags & PARSING)) { + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDPORT_STR, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set Port value '%s'", + count, p); + } +@@ -396,7 +396,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + if (p && (*parser_flags & PARSING)) { + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_CIPHERS_C_S, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set C->S Ciphers value '%s'", + count, p); + break; +@@ -404,7 +404,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_CIPHERS_S_C, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set S->C Ciphers value '%s'", + count, p); + } +@@ -415,7 +415,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + if (p && (*parser_flags & PARSING)) { + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HMAC_C_S, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set C->S MAC value '%s'", + count, p); + break; +@@ -423,7 +423,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HMAC_S_C, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set S->C MAC value '%s'", + count, p); + } +@@ -453,7 +453,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_LOG_VERBOSITY, + &value); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set LogLevel value '%s'", + count, p); + } +@@ -465,7 +465,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + if (p && (*parser_flags & PARSING)) { + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_KEY_EXCHANGE, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set KexAlgorithms value '%s'", + count, p); + } +@@ -540,7 +540,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + /* Skip one argument */ + p = ssh_config_get_str_tok(&s, NULL); + if (p == NULL || p[0] == '\0') { +- SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword " ++ SSH_LOG(SSH_LOG_TRACE, "line %d: Match keyword " + "'%s' requires argument\n", count, p2); + SAFE_FREE(x); + return -1; +@@ -576,7 +576,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + rc = ssh_bind_options_set(bind, + SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set PubKeyAcceptedKeyTypes value '%s'", + count, p); + } +@@ -588,7 +588,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + rc = ssh_bind_options_set(bind, + SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS, p); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set HostkeyAlgorithms value '%s'", + count, p); + } +@@ -599,15 +599,15 @@ ssh_bind_config_parse_line(ssh_bind bind, + keyword, count); + break; + case BIND_CFG_UNKNOWN: +- SSH_LOG(SSH_LOG_WARN, "Unknown option: %s, line: %d", ++ SSH_LOG(SSH_LOG_TRACE, "Unknown option: %s, line: %d", + keyword, count); + break; + case BIND_CFG_UNSUPPORTED: +- SSH_LOG(SSH_LOG_WARN, "Unsupported option: %s, line: %d", ++ SSH_LOG(SSH_LOG_TRACE, "Unsupported option: %s, line: %d", + keyword, count); + break; + case BIND_CFG_NA: +- SSH_LOG(SSH_LOG_WARN, "Option not applicable: %s, line: %d", ++ SSH_LOG(SSH_LOG_TRACE, "Option not applicable: %s, line: %d", + keyword, count); + break; + default: +diff --git a/src/buffer.c b/src/buffer.c +index e0068015..0685b762 100644 +--- a/src/buffer.c ++++ b/src/buffer.c +@@ -878,7 +878,7 @@ static int ssh_buffer_pack_allocate_va(struct ssh_buffer_struct *buffer, + cstring = NULL; + break; + default: +- SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid buffer format %c", *p); + rc = SSH_ERROR; + } + if (rc != SSH_OK){ +@@ -1007,7 +1007,7 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer, + cstring = NULL; + break; + default: +- SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid buffer format %c", *p); + rc = SSH_ERROR; + } + if (rc != SSH_OK){ +@@ -1239,7 +1239,7 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer, + rc = SSH_OK; + break; + default: +- SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid buffer format %c", *p); + } + if (rc != SSH_OK) { + break; +diff --git a/src/channels.c b/src/channels.c +index 1d422801..73a6ffe4 100644 +--- a/src/channels.c ++++ b/src/channels.c +@@ -1453,7 +1453,7 @@ static int channel_write_common(ssh_channel channel, + } + + if (len > INT_MAX) { +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_TRACE, + "Length (%u) is bigger than INT_MAX", len); + return SSH_ERROR; + } +diff --git a/src/client.c b/src/client.c +index a35a28e1..7a967048 100644 +--- a/src/client.c ++++ b/src/client.c +@@ -73,7 +73,7 @@ static void socket_callback_connected(int code, int errno_code, void *user) + return; + } + +- SSH_LOG(SSH_LOG_RARE,"Socket connection callback: %d (%d)",code, errno_code); ++ SSH_LOG(SSH_LOG_TRACE,"Socket connection callback: %d (%d)",code, errno_code); + if(code == SSH_SOCKET_CONNECTED_OK) + session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED; + else { +diff --git a/src/config.c b/src/config.c +index 927225ae..ae2a0c4c 100644 +--- a/src/config.c ++++ b/src/config.c +@@ -500,7 +500,7 @@ ssh_config_parse_proxy_jump(ssh_session session, const char *s, bool do_parsing) + next ? next : "", + hostname); + if (rv < 0 || rv >= (int)sizeof(com)) { +- SSH_LOG(SSH_LOG_WARN, "Too long ProxyJump configuration line"); ++ SSH_LOG(SSH_LOG_TRACE, "Too long ProxyJump configuration line"); + rv = SSH_ERROR; + goto out; + } +@@ -711,7 +711,7 @@ ssh_config_parse_line(ssh_session session, + /* Skip one argument (including in quotes) */ + p = ssh_config_get_token(&s); + if (p == NULL || p[0] == '\0') { +- SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword " ++ SSH_LOG(SSH_LOG_TRACE, "line %d: Match keyword " + "'%s' requires argument", count, p2); + SAFE_FREE(x); + return -1; +@@ -738,7 +738,7 @@ ssh_config_parse_line(ssh_session session, + } + localuser = ssh_get_local_username(); + if (localuser == NULL) { +- SSH_LOG(SSH_LOG_WARN, "line %d: Can not get local username " ++ SSH_LOG(SSH_LOG_TRACE, "line %d: Can not get local username " + "for conditional matching.", count); + SAFE_FREE(x); + return -1; +@@ -752,13 +752,13 @@ ssh_config_parse_line(ssh_session session, + /* Skip one argument */ + p = ssh_config_get_str_tok(&s, NULL); + if (p == NULL || p[0] == '\0') { +- SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword " ++ SSH_LOG(SSH_LOG_TRACE, "line %d: Match keyword " + "'%s' requires argument", count, p2); + SAFE_FREE(x); + return -1; + } + args++; +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_TRACE, + "line %d: Unsupported Match keyword '%s', ignoring", + count, + p2); +@@ -1013,13 +1013,13 @@ ssh_config_parse_line(ssh_session session, + ll = strtoll(p, &endp, 10); + if (p == endp || ll < 0) { + /* No number or negative */ +- SSH_LOG(SSH_LOG_WARN, "Invalid argument to rekey limit"); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid argument to rekey limit"); + break; + } + switch (*endp) { + case 'G': + if (ll > LLONG_MAX / 1024) { +- SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); ++ SSH_LOG(SSH_LOG_TRACE, "Possible overflow of rekey limit"); + ll = -1; + break; + } +@@ -1027,7 +1027,7 @@ ssh_config_parse_line(ssh_session session, + FALL_THROUGH; + case 'M': + if (ll > LLONG_MAX / 1024) { +- SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); ++ SSH_LOG(SSH_LOG_TRACE, "Possible overflow of rekey limit"); + ll = -1; + break; + } +@@ -1035,7 +1035,7 @@ ssh_config_parse_line(ssh_session session, + FALL_THROUGH; + case 'K': + if (ll > LLONG_MAX / 1024) { +- SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); ++ SSH_LOG(SSH_LOG_TRACE, "Possible overflow of rekey limit"); + ll = -1; + break; + } +@@ -1051,7 +1051,7 @@ ssh_config_parse_line(ssh_session session, + break; + } + if (*endp != ' ' && *endp != '\0') { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Invalid trailing characters after the rekey limit: %s", + endp); + break; +@@ -1072,14 +1072,14 @@ ssh_config_parse_line(ssh_session session, + ll = strtoll(p, &endp, 10); + if (p == endp || ll < 0) { + /* No number or negative */ +- SSH_LOG(SSH_LOG_WARN, "Invalid argument to rekey limit"); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid argument to rekey limit"); + break; + } + switch (*endp) { + case 'w': + case 'W': + if (ll > LLONG_MAX / 7) { +- SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); ++ SSH_LOG(SSH_LOG_TRACE, "Possible overflow of rekey limit"); + ll = -1; + break; + } +@@ -1088,7 +1088,7 @@ ssh_config_parse_line(ssh_session session, + case 'd': + case 'D': + if (ll > LLONG_MAX / 24) { +- SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); ++ SSH_LOG(SSH_LOG_TRACE, "Possible overflow of rekey limit"); + ll = -1; + break; + } +@@ -1097,7 +1097,7 @@ ssh_config_parse_line(ssh_session session, + case 'h': + case 'H': + if (ll > LLONG_MAX / 60) { +- SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); ++ SSH_LOG(SSH_LOG_TRACE, "Possible overflow of rekey limit"); + ll = -1; + break; + } +@@ -1106,7 +1106,7 @@ ssh_config_parse_line(ssh_session session, + case 'm': + case 'M': + if (ll > LLONG_MAX / 60) { +- SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); ++ SSH_LOG(SSH_LOG_TRACE, "Possible overflow of rekey limit"); + ll = -1; + break; + } +@@ -1125,7 +1125,7 @@ ssh_config_parse_line(ssh_session session, + break; + } + if (*endp != '\0') { +- SSH_LOG(SSH_LOG_WARN, "Invalid trailing characters after the" ++ SSH_LOG(SSH_LOG_TRACE, "Invalid trailing characters after the" + " rekey limit: %s", endp); + break; + } +@@ -1161,7 +1161,7 @@ ssh_config_parse_line(ssh_session session, + } + break; + case SOC_NA: +- SSH_LOG(SSH_LOG_INFO, "Unapplicable option: %s, line: %d", ++ SSH_LOG(SSH_LOG_TRACE, "Unapplicable option: %s, line: %d", + keyword, count); + break; + case SOC_UNSUPPORTED: +@@ -1169,7 +1169,7 @@ ssh_config_parse_line(ssh_session session, + keyword, count); + break; + case SOC_UNKNOWN: +- SSH_LOG(SSH_LOG_INFO, "Unknown option: %s, line: %d", ++ SSH_LOG(SSH_LOG_TRACE, "Unknown option: %s, line: %d", + keyword, count); + break; + case SOC_IDENTITYAGENT: +@@ -1260,12 +1260,12 @@ int ssh_config_parse_string(ssh_session session, const char *input) + } + if (c == NULL) { + /* should not happen, would mean a string without trailing '\0' */ +- SSH_LOG(SSH_LOG_WARN, "No trailing '\\0' in config string"); ++ SSH_LOG(SSH_LOG_TRACE, "No trailing '\\0' in config string"); + return SSH_ERROR; + } + line_len = c - line_start; + if (line_len > MAX_LINE_SIZE - 1) { +- SSH_LOG(SSH_LOG_WARN, "Line %u too long: %u characters", ++ SSH_LOG(SSH_LOG_TRACE, "Line %u too long: %u characters", + line_num, line_len); + return SSH_ERROR; + } +diff --git a/src/config_parser.c b/src/config_parser.c +index 2f91d39f..d0919eea 100644 +--- a/src/config_parser.c ++++ b/src/config_parser.c +@@ -246,7 +246,7 @@ int ssh_config_parse_uri(const char *tok, + /* Verify the port is valid positive number */ + port_n = strtol(endp + 1, &port_end, 10); + if (port_n < 1 || *port_end != '\0') { +- SSH_LOG(SSH_LOG_WARN, "Failed to parse port number." ++ SSH_LOG(SSH_LOG_TRACE, "Failed to parse port number." + " The value '%ld' is invalid or there are some" + " trailing characters: '%s'", port_n, port_end); + goto error; +diff --git a/src/error.c b/src/error.c +index 8930d26a..c69fbbfa 100644 +--- a/src/error.c ++++ b/src/error.c +@@ -63,8 +63,8 @@ void _ssh_set_error(void *error, + va_end(va); + + err->error.error_code = code; +- if (ssh_get_log_level() >= SSH_LOG_WARN) { +- ssh_log_function(SSH_LOG_WARN, ++ if (ssh_get_log_level() == SSH_LOG_TRACE) { ++ ssh_log_function(SSH_LOG_TRACE, + function, + err->error.error_buffer); + } +diff --git a/src/gssapi.c b/src/gssapi.c +index bbfcb6e6..f60f8d72 100644 +--- a/src/gssapi.c ++++ b/src/gssapi.c +@@ -246,7 +246,7 @@ ssh_gssapi_handle_userauth(ssh_session session, const char *user, + continue; + } + if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){ +- SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID"); ++ SSH_LOG(SSH_LOG_TRACE,"GSSAPI: received invalid OID"); + continue; + } + oid.elements = &oid_s[2]; +@@ -288,8 +288,8 @@ ssh_gssapi_handle_userauth(ssh_session session, const char *user, + gss_release_oid_set(&min_stat, &both_supported); + + if (maj_stat != GSS_S_COMPLETE) { +- SSH_LOG(SSH_LOG_WARNING, "error acquiring credentials %d, %d", maj_stat, min_stat); +- ssh_gssapi_log_error(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_TRACE, "error acquiring credentials %d, %d", maj_stat, min_stat); ++ ssh_gssapi_log_error(SSH_LOG_TRACE, + "acquiring creds", + maj_stat, + min_stat); +@@ -308,7 +308,7 @@ ssh_gssapi_handle_userauth(ssh_session session, const char *user, + continue; + } + if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){ +- SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID"); ++ SSH_LOG(SSH_LOG_TRACE,"GSSAPI: received invalid OID"); + continue; + } + oid.elements = &oid_s[2]; +diff --git a/src/kex.c b/src/kex.c +index 192eb881..52d9c2ee 100644 +--- a/src/kex.c ++++ b/src/kex.c +@@ -601,7 +601,7 @@ char *ssh_client_select_hostkeys(ssh_session session) + /* 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, ++ SSH_LOG(SSH_LOG_TRACE, + "List of allowed host key algorithms is empty or contains only " + "unsupported algorithms"); + return NULL; +@@ -654,7 +654,7 @@ char *ssh_client_select_hostkeys(ssh_session session) + fips_hostkeys = ssh_keep_fips_algos(SSH_HOSTKEYS, new_hostkeys); + SAFE_FREE(new_hostkeys); + if (fips_hostkeys == NULL) { +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_TRACE, + "None of the wanted host keys or keys in known_hosts files " + "is allowed in FIPS mode."); + return NULL; +@@ -1141,7 +1141,7 @@ int ssh_make_sessionid(ssh_session session) + case SSH_KEX_ECDH_SHA2_NISTP521: + if (session->next_crypto->ecdh_client_pubkey == NULL || + session->next_crypto->ecdh_server_pubkey == NULL) { +- SSH_LOG(SSH_LOG_WARNING, "ECDH parameted missing"); ++ SSH_LOG(SSH_LOG_TRACE, "ECDH parameted missing"); + goto error; + } + rc = ssh_buffer_pack(buf, +diff --git a/src/knownhosts.c b/src/knownhosts.c +index 49bdf574..1f52dedc 100644 +--- a/src/knownhosts.c ++++ b/src/knownhosts.c +@@ -235,7 +235,7 @@ static int ssh_known_hosts_read_entries(const char *match, + fp = fopen(filename, "r"); + if (fp == NULL) { + char err_msg[SSH_ERRNO_MSG_MAX] = {0}; +- SSH_LOG(SSH_LOG_WARN, "Failed to open the known_hosts file '%s': %s", ++ SSH_LOG(SSH_LOG_TRACE, "Failed to open the known_hosts file '%s': %s", + filename, ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); + /* The missing file is not an error here */ + return SSH_OK; +@@ -503,7 +503,7 @@ static const char *ssh_known_host_sigs_from_hostkey_type(enum ssh_keytypes_e typ + #endif + case SSH_KEYTYPE_UNKNOWN: + default: +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "The given type %d is not a base private key type " + "or is unsupported", + type); +@@ -749,7 +749,7 @@ int ssh_known_hosts_parse_line(const char *hostname, + + key_type = ssh_key_type_from_name(p); + if (key_type == SSH_KEYTYPE_UNKNOWN) { +- SSH_LOG(SSH_LOG_WARN, "key type '%s' unknown!", p); ++ SSH_LOG(SSH_LOG_TRACE, "key type '%s' unknown!", p); + rc = SSH_ERROR; + goto out; + } +@@ -765,7 +765,7 @@ int ssh_known_hosts_parse_line(const char *hostname, + key_type, + &e->publickey); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Failed to parse %s key for entry: %s!", + ssh_key_type_to_char(key_type), + e->unparsed); +@@ -836,7 +836,7 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session) + if (session->opts.knownhosts != NULL) { + known_hosts_found = ssh_file_readaccess_ok(session->opts.knownhosts); + if (!known_hosts_found) { +- SSH_LOG(SSH_LOG_WARN, "Cannot access file %s", ++ SSH_LOG(SSH_LOG_TRACE, "Cannot access file %s", + session->opts.knownhosts); + } + } +@@ -845,7 +845,7 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session) + global_known_hosts_found = + ssh_file_readaccess_ok(session->opts.global_knownhosts); + if (!global_known_hosts_found) { +- SSH_LOG(SSH_LOG_WARN, "Cannot access file %s", ++ SSH_LOG(SSH_LOG_TRACE, "Cannot access file %s", + session->opts.global_knownhosts); + } + } +diff --git a/src/libcrypto.c b/src/libcrypto.c +index 468b63f0..d2fe2289 100644 +--- a/src/libcrypto.c ++++ b/src/libcrypto.c +@@ -104,7 +104,7 @@ ENGINE *pki_get_engine(void) + + engine = ENGINE_by_id("pkcs11"); + if (engine == NULL) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Could not load the engine: %s", + ERR_error_string(ERR_get_error(), NULL)); + return NULL; +@@ -113,7 +113,7 @@ ENGINE *pki_get_engine(void) + + ok = ENGINE_init(engine); + if (!ok) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Could not initialize the engine: %s", + ERR_error_string(ERR_get_error(), NULL)); + ENGINE_free(engine); +@@ -444,10 +444,10 @@ static void evp_cipher_init(struct ssh_cipher_struct *cipher) + /* ciphers not using EVP */ + #endif /* WITH_BLOWFISH_CIPHER */ + case SSH_AEAD_CHACHA20_POLY1305: +- SSH_LOG(SSH_LOG_WARNING, "The ChaCha cipher cannot be handled here"); ++ SSH_LOG(SSH_LOG_TRACE, "The ChaCha cipher cannot be handled here"); + break; + case SSH_NO_CIPHER: +- SSH_LOG(SSH_LOG_WARNING, "No valid ciphertype found"); ++ SSH_LOG(SSH_LOG_TRACE, "No valid ciphertype found"); + break; + } + } +@@ -461,7 +461,7 @@ static int evp_cipher_set_encrypt_key(struct ssh_cipher_struct *cipher, + + rc = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV); + if (rc != 1){ +- SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptInit_ex failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptInit_ex failed"); + return SSH_ERROR; + } + +@@ -473,7 +473,7 @@ static int evp_cipher_set_encrypt_key(struct ssh_cipher_struct *cipher, + -1, + (uint8_t *)IV); + if (rc != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_SET_IV_FIXED failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_SET_IV_FIXED failed"); + return SSH_ERROR; + } + } +@@ -491,7 +491,7 @@ static int evp_cipher_set_decrypt_key(struct ssh_cipher_struct *cipher, + + rc = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV); + if (rc != 1){ +- SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptInit_ex failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_DecryptInit_ex failed"); + return SSH_ERROR; + } + +@@ -503,7 +503,7 @@ static int evp_cipher_set_decrypt_key(struct ssh_cipher_struct *cipher, + -1, + (uint8_t *)IV); + if (rc != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_SET_IV_FIXED failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_SET_IV_FIXED failed"); + return SSH_ERROR; + } + } +@@ -528,7 +528,7 @@ static void evp_cipher_encrypt(struct ssh_cipher_struct *cipher, + (unsigned char *)in, + (int)len); + if (rc != 1){ +- SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptUpdate failed"); + return; + } + if (outlen != (int)len){ +@@ -554,7 +554,7 @@ static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher, + (unsigned char *)in, + (int)len); + if (rc != 1){ +- SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_DecryptUpdate failed"); + return; + } + if (outlen != (int)len){ +@@ -613,7 +613,7 @@ evp_cipher_aead_encrypt(struct ssh_cipher_struct *cipher, + 1, + lastiv); + if (rc == 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_IV_GEN failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_IV_GEN failed"); + return; + } + +@@ -625,7 +625,7 @@ evp_cipher_aead_encrypt(struct ssh_cipher_struct *cipher, + (int)aadlen); + outlen = tmplen; + if (rc == 0 || outlen != aadlen) { +- SSH_LOG(SSH_LOG_WARNING, "Failed to pass authenticated data"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to pass authenticated data"); + return; + } + memcpy(out, in, aadlen); +@@ -638,7 +638,7 @@ evp_cipher_aead_encrypt(struct ssh_cipher_struct *cipher, + (int)len - aadlen); + outlen = tmplen; + if (rc != 1 || outlen != (int)len - aadlen) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptUpdate failed"); + return; + } + +@@ -647,7 +647,7 @@ evp_cipher_aead_encrypt(struct ssh_cipher_struct *cipher, + NULL, + &tmplen); + if (rc < 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptFinal failed: Failed to create a tag"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptFinal failed: Failed to create a tag"); + return; + } + +@@ -656,7 +656,7 @@ evp_cipher_aead_encrypt(struct ssh_cipher_struct *cipher, + authlen, + (unsigned char *)tag); + if (rc != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_GET_TAG failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_GET_TAG failed"); + return; + } + } +@@ -684,7 +684,7 @@ evp_cipher_aead_decrypt(struct ssh_cipher_struct *cipher, + 1, + lastiv); + if (rc == 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_IV_GEN failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_IV_GEN failed"); + return SSH_ERROR; + } + +@@ -694,7 +694,7 @@ evp_cipher_aead_decrypt(struct ssh_cipher_struct *cipher, + authlen, + (unsigned char *)complete_packet + aadlen + encrypted_size); + if (rc == 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_SET_TAG failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_SET_TAG failed"); + return SSH_ERROR; + } + +@@ -705,7 +705,7 @@ evp_cipher_aead_decrypt(struct ssh_cipher_struct *cipher, + (unsigned char *)complete_packet, + (int)aadlen); + if (rc == 0) { +- SSH_LOG(SSH_LOG_WARNING, "Failed to pass authenticated data"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to pass authenticated data"); + return SSH_ERROR; + } + /* Do not copy the length to the target buffer, because it is already processed */ +@@ -718,12 +718,12 @@ evp_cipher_aead_decrypt(struct ssh_cipher_struct *cipher, + (unsigned char *)complete_packet + aadlen, + encrypted_size /* already substracted aadlen*/); + if (rc != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_DecryptUpdate failed"); + return SSH_ERROR; + } + + if (outlen != (int)encrypted_size) { +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_TRACE, + "EVP_DecryptUpdate: output size %d for %zd in", + outlen, + encrypted_size); +@@ -735,7 +735,7 @@ evp_cipher_aead_decrypt(struct ssh_cipher_struct *cipher, + NULL, + &outlen); + if (rc < 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptFinal failed: Failed authentication"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_DecryptFinal failed: Failed authentication"); + return SSH_ERROR; + } + +@@ -817,24 +817,24 @@ chacha20_poly1305_set_key(struct ssh_cipher_struct *cipher, + /* K2 uses the first half of the key */ + ctx->main_evp = EVP_CIPHER_CTX_new(); + if (ctx->main_evp == NULL) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CIPHER_CTX_new failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CIPHER_CTX_new failed"); + goto out; + } + rv = EVP_EncryptInit_ex(ctx->main_evp, EVP_chacha20(), NULL, u8key, NULL); + if (rv != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherInit failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit failed"); + goto out; + } + /* K1 uses the second half of the key */ + ctx->header_evp = EVP_CIPHER_CTX_new(); + if (ctx->header_evp == NULL) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CIPHER_CTX_new failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CIPHER_CTX_new failed"); + goto out; + } + ret = EVP_EncryptInit_ex(ctx->header_evp, EVP_chacha20(), NULL, + u8key + CHACHA20_KEYLEN, NULL); + if (ret != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherInit failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit failed"); + goto out; + } + +@@ -844,18 +844,18 @@ chacha20_poly1305_set_key(struct ssh_cipher_struct *cipher, + #if OPENSSL_VERSION_NUMBER < 0x30000000L + ctx->mctx = EVP_MD_CTX_new(); + if (ctx->mctx == NULL) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_MD_CTX_new failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_MD_CTX_new failed"); + return SSH_ERROR; + } + #else + mac = EVP_MAC_fetch(NULL, "poly1305", NULL); + if (mac == NULL) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_fetch failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_fetch failed"); + goto out; + } + ctx->mctx = EVP_MAC_CTX_new(mac); + if (ctx->mctx == NULL) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_CTX_new failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_CTX_new failed"); + goto out; + } + #endif /* OPENSSL_VERSION_NUMBER */ +@@ -893,13 +893,13 @@ chacha20_poly1305_set_iv(struct ssh_cipher_struct *cipher, + + ret = EVP_CipherInit_ex(ctx->header_evp, NULL, NULL, NULL, seqbuf, do_encrypt); + if (ret != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherInit_ex(header_evp) failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit_ex(header_evp) failed"); + return SSH_ERROR; + } + + ret = EVP_CipherInit_ex(ctx->main_evp, NULL, NULL, NULL, seqbuf, do_encrypt); + if (ret != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherInit_ex(main_evp) failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit_ex(main_evp) failed"); + return SSH_ERROR; + } + +@@ -928,7 +928,7 @@ chacha20_poly1305_packet_setup(struct ssh_cipher_struct *cipher, + rv = EVP_CipherUpdate(ctx->main_evp, poly_key, &len, + (unsigned char *)zero_block, sizeof(zero_block)); + if (rv != 1 || len != CHACHA20_BLOCKSIZE) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptUpdate failed"); + goto out; + } + #ifdef DEBUG_CRYPTO +@@ -942,12 +942,12 @@ chacha20_poly1305_packet_setup(struct ssh_cipher_struct *cipher, + ctx->key = EVP_PKEY_new_mac_key(EVP_PKEY_POLY1305, NULL, + poly_key, POLY1305_KEYLEN); + if (ctx->key == NULL) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_PKEY_new_mac_key failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_PKEY_new_mac_key failed"); + goto out; + } + rv = EVP_DigestSignInit(ctx->mctx, &ctx->pctx, NULL, NULL, ctx->key); + if (rv != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_DigestSignInit failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_DigestSignInit failed"); + goto out; + } + } else { +@@ -956,14 +956,14 @@ chacha20_poly1305_packet_setup(struct ssh_cipher_struct *cipher, + EVP_PKEY_CTRL_SET_MAC_KEY, + POLY1305_KEYLEN, (void *)poly_key); + if (rv <= 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_PKEY_CTX_ctrl failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_PKEY_CTX_ctrl failed"); + goto out; + } + } + #else + rv = EVP_MAC_init(ctx->mctx, poly_key, POLY1305_KEYLEN, NULL); + if (rv != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_init failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_init failed"); + goto out; + } + #endif /* OPENSSL_VERSION_NUMBER */ +@@ -1000,7 +1000,7 @@ chacha20_poly1305_aead_decrypt_length(struct ssh_cipher_struct *cipher, + + rv = EVP_CipherUpdate(ctx->header_evp, out, &outlen, in, len); + if (rv != 1 || outlen != sizeof(uint32_t)) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherUpdate failed"); + return SSH_ERROR; + } + +@@ -1010,7 +1010,7 @@ chacha20_poly1305_aead_decrypt_length(struct ssh_cipher_struct *cipher, + + rv = EVP_CipherFinal_ex(ctx->header_evp, out + outlen, &outlen); + if (rv != 1 || outlen != 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherFinal_ex failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherFinal_ex failed"); + return SSH_ERROR; + } + +@@ -1035,7 +1035,7 @@ chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + /* Prepare the Poly1305 key */ + rv = chacha20_poly1305_packet_setup(cipher, seq, 0); + if (rv != SSH_OK) { +- SSH_LOG(SSH_LOG_WARNING, "Failed to setup packet"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to setup packet"); + goto out; + } + +@@ -1048,26 +1048,26 @@ chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + rv = EVP_DigestSignUpdate(ctx->mctx, complete_packet, + encrypted_size + sizeof(uint32_t)); + if (rv != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_DigestSignUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_DigestSignUpdate failed"); + goto out; + } + + rv = EVP_DigestSignFinal(ctx->mctx, tag, &taglen); + if (rv != 1) { +- SSH_LOG(SSH_LOG_WARNING, "poly1305 verify error"); ++ SSH_LOG(SSH_LOG_TRACE, "poly1305 verify error"); + goto out; + } + #else + rv = EVP_MAC_update(ctx->mctx, complete_packet, + encrypted_size + sizeof(uint32_t)); + if (rv != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_update failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_update failed"); + goto out; + } + + rv = EVP_MAC_final(ctx->mctx, tag, &taglen, POLY1305_TAGLEN); + if (rv != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_final failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_final failed"); + goto out; + } + #endif /* OPENSSL_VERSION_NUMBER */ +@@ -1089,13 +1089,13 @@ chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + (uint8_t *)complete_packet + sizeof(uint32_t), + encrypted_size); + if (rv != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherUpdate failed"); + goto out; + } + + rv = EVP_CipherFinal_ex(ctx->main_evp, out + len, &len); + if (rv != 1 || len != 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherFinal_ex failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherFinal_ex failed"); + goto out; + } + +@@ -1120,7 +1120,7 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + /* Prepare the Poly1305 key */ + ret = chacha20_poly1305_packet_setup(cipher, seq, 1); + if (ret != SSH_OK) { +- SSH_LOG(SSH_LOG_WARNING, "Failed to setup packet"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to setup packet"); + return; + } + +@@ -1135,7 +1135,7 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + (unsigned char *)&in_packet->length, + sizeof(uint32_t)); + if (ret != 1 || outlen != sizeof(uint32_t)) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherUpdate failed"); + return; + } + #ifdef DEBUG_CRYPTO +@@ -1144,7 +1144,7 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + #endif /* DEBUG_CRYPTO */ + ret = EVP_CipherFinal_ex(ctx->header_evp, (uint8_t *)out + outlen, &outlen); + if (ret != 1 || outlen != 0) { +- SSH_LOG(SSH_LOG_PACKET, "EVP_EncryptFinal_ex failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptFinal_ex failed"); + return; + } + +@@ -1156,7 +1156,7 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + in_packet->payload, + len - sizeof(uint32_t)); + if (ret != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_CipherUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_CipherUpdate failed"); + return; + } + +@@ -1164,24 +1164,24 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + #if OPENSSL_VERSION_NUMBER < 0x30000000L + ret = EVP_DigestSignUpdate(ctx->mctx, out_packet, len); + if (ret <= 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_DigestSignUpdate failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_DigestSignUpdate failed"); + return; + } + ret = EVP_DigestSignFinal(ctx->mctx, tag, &taglen); + if (ret <= 0) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_DigestSignFinal failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_DigestSignFinal failed"); + return; + } + #else + ret = EVP_MAC_update(ctx->mctx, (void*)out_packet, len); + if (ret != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_update failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_update failed"); + return; + } + + ret = EVP_MAC_final(ctx->mctx, tag, &taglen, POLY1305_TAGLEN); + if (ret != 1) { +- SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_final failed"); ++ SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_final failed"); + return; + } + #endif /* OPENSSL_VERSION_NUMBER */ +diff --git a/src/libgcrypt.c b/src/libgcrypt.c +index da5588ad..a450e78a 100644 +--- a/src/libgcrypt.c ++++ b/src/libgcrypt.c +@@ -241,7 +241,7 @@ static int aes_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) { + } + break; + default: +- SSH_LOG(SSH_LOG_WARNING, "Unksupported key length %u.", cipher->keysize); ++ SSH_LOG(SSH_LOG_TRACE, "Unsupported key length %u.", cipher->keysize); + SAFE_FREE(cipher->key); + return -1; + } +@@ -334,7 +334,7 @@ aes_gcm_encrypt(struct ssh_cipher_struct *cipher, + */ + uint64_inc(cipher->last_iv + 4); + if (err) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_setiv failed: %s", + gpg_strerror(err)); + return; + } +@@ -342,7 +342,7 @@ aes_gcm_encrypt(struct ssh_cipher_struct *cipher, + /* Pass the authenticated data (packet_length) */ + err = gcry_cipher_authenticate(cipher->key[0], in, aadlen); + if (err) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_authenticate failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_authenticate failed: %s", + gpg_strerror(err)); + return; + } +@@ -355,7 +355,7 @@ aes_gcm_encrypt(struct ssh_cipher_struct *cipher, + (unsigned char *)in + aadlen, + len - aadlen); + if (err) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_encrypt failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_encrypt failed: %s", + gpg_strerror(err)); + return; + } +@@ -365,7 +365,7 @@ aes_gcm_encrypt(struct ssh_cipher_struct *cipher, + (void *)tag, + authlen); + if (err) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_gettag failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_gettag failed: %s", + gpg_strerror(err)); + return; + } +@@ -399,7 +399,7 @@ aes_gcm_decrypt(struct ssh_cipher_struct *cipher, + */ + uint64_inc(cipher->last_iv + 4); + if (err) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_setiv failed: %s", + gpg_strerror(err)); + return SSH_ERROR; + } +@@ -409,7 +409,7 @@ aes_gcm_decrypt(struct ssh_cipher_struct *cipher, + complete_packet, + aadlen); + if (err) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_authenticate failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_authenticate failed: %s", + gpg_strerror(err)); + return SSH_ERROR; + } +@@ -423,7 +423,7 @@ aes_gcm_decrypt(struct ssh_cipher_struct *cipher, + (unsigned char *)complete_packet + aadlen, + encrypted_size); + if (err) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_decrypt failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_decrypt failed: %s", + gpg_strerror(err)); + return SSH_ERROR; + } +@@ -436,7 +436,7 @@ aes_gcm_decrypt(struct ssh_cipher_struct *cipher, + SSH_LOG(SSH_LOG_WARNING, "The authentication tag does not match"); + return SSH_ERROR; + } else if (err != GPG_ERR_NO_ERROR) { +- SSH_LOG(SSH_LOG_WARNING, "General error while decryption: %s", ++ SSH_LOG(SSH_LOG_TRACE, "General error while decryption: %s", + gpg_strerror(err)); + return SSH_ERROR; + } +@@ -522,7 +522,7 @@ static int chacha20_set_encrypt_key(struct ssh_cipher_struct *cipher, + err = gcry_cipher_open(&ctx->main_hd, GCRY_CIPHER_CHACHA20, + GCRY_CIPHER_MODE_STREAM, 0); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_open failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_open failed: %s", + gpg_strerror(err)); + SAFE_FREE(cipher->chacha20_schedule); + return -1; +@@ -530,7 +530,7 @@ static int chacha20_set_encrypt_key(struct ssh_cipher_struct *cipher, + err = gcry_cipher_open(&ctx->header_hd, GCRY_CIPHER_CHACHA20, + GCRY_CIPHER_MODE_STREAM, 0); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_open failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_open failed: %s", + gpg_strerror(err)); + gcry_cipher_close(ctx->main_hd); + SAFE_FREE(cipher->chacha20_schedule); +@@ -538,7 +538,7 @@ static int chacha20_set_encrypt_key(struct ssh_cipher_struct *cipher, + } + err = gcry_mac_open(&ctx->mac_hd, GCRY_MAC_POLY1305, 0, NULL); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_mac_open failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_mac_open failed: %s", + gpg_strerror(err)); + gcry_cipher_close(ctx->main_hd); + gcry_cipher_close(ctx->header_hd); +@@ -551,7 +551,7 @@ static int chacha20_set_encrypt_key(struct ssh_cipher_struct *cipher, + + err = gcry_cipher_setkey(ctx->main_hd, u8key, CHACHA20_KEYLEN); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setkey failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_setkey failed: %s", + gpg_strerror(err)); + chacha20_cleanup(cipher); + return -1; +@@ -560,7 +560,7 @@ static int chacha20_set_encrypt_key(struct ssh_cipher_struct *cipher, + err = gcry_cipher_setkey(ctx->header_hd, u8key + CHACHA20_KEYLEN, + CHACHA20_KEYLEN); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setkey failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_setkey failed: %s", + gpg_strerror(err)); + chacha20_cleanup(cipher); + return -1; +@@ -587,7 +587,7 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + /* step 1, prepare the poly1305 key */ + err = gcry_cipher_setiv(ctx->main_hd, (uint8_t *)&seq, sizeof(seq)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_setiv failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -599,13 +599,13 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + zero_block, + sizeof(zero_block)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_encrypt failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_encrypt failed: %s", + gpg_strerror(err)); + goto out; + } + err = gcry_mac_setkey(ctx->mac_hd, poly_key, POLY1305_KEYLEN); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_mac_setkey failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_mac_setkey failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -613,7 +613,7 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + /* step 2, encrypt length field */ + err = gcry_cipher_setiv(ctx->header_hd, (uint8_t *)&seq, sizeof(seq)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_setiv failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -623,7 +623,7 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + (uint8_t *)&in_packet->length, + sizeof(uint32_t)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_encrypt failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_encrypt failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -635,7 +635,7 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + in_packet->payload, + len - sizeof(uint32_t)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_encrypt failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_encrypt failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -643,13 +643,13 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + /* step 4, compute the MAC */ + err = gcry_mac_write(ctx->mac_hd, (uint8_t *)out_packet, len); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_mac_write failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_mac_write failed: %s", + gpg_strerror(err)); + goto out; + } + err = gcry_mac_read(ctx->mac_hd, tag, &taglen); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_mac_read failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_mac_read failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -675,7 +675,7 @@ static int chacha20_poly1305_aead_decrypt_length( + + err = gcry_cipher_setiv(ctx->header_hd, (uint8_t *)&seq, sizeof(seq)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_setiv failed: %s", + gpg_strerror(err)); + return SSH_ERROR; + } +@@ -685,7 +685,7 @@ static int chacha20_poly1305_aead_decrypt_length( + in, + sizeof(uint32_t)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_decrypt failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_decrypt failed: %s", + gpg_strerror(err)); + return SSH_ERROR; + } +@@ -711,7 +711,7 @@ static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + /* step 1, prepare the poly1305 key */ + err = gcry_cipher_setiv(ctx->main_hd, (uint8_t *)&seq, sizeof(seq)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_setiv failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -723,13 +723,13 @@ static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + zero_block, + sizeof(zero_block)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_encrypt failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_encrypt failed: %s", + gpg_strerror(err)); + goto out; + } + err = gcry_mac_setkey(ctx->mac_hd, poly_key, POLY1305_KEYLEN); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_mac_setkey failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_mac_setkey failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -738,7 +738,7 @@ static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + err = gcry_mac_write(ctx->mac_hd, (uint8_t *)complete_packet, + encrypted_size + sizeof(uint32_t)); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_mac_write failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_mac_write failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -747,7 +747,7 @@ static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + SSH_LOG(SSH_LOG_PACKET, "poly1305 verify error"); + goto out; + } else if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_mac_verify failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_mac_verify failed: %s", + gpg_strerror(err)); + goto out; + } +@@ -759,7 +759,7 @@ static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + (uint8_t *)complete_packet + sizeof(uint32_t), + encrypted_size); + if (err != 0) { +- SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_decrypt failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "gcry_cipher_decrypt failed: %s", + gpg_strerror(err)); + goto out; + } +diff --git a/src/libmbedcrypto.c b/src/libmbedcrypto.c +index 6d84bd51..e3baecca 100644 +--- a/src/libmbedcrypto.c ++++ b/src/libmbedcrypto.c +@@ -217,7 +217,7 @@ cipher_init(struct ssh_cipher_struct *cipher, + } else if (operation == MBEDTLS_DECRYPT) { + ctx = &cipher->decrypt_ctx; + } else { +- SSH_LOG(SSH_LOG_WARNING, "unknown operation"); ++ SSH_LOG(SSH_LOG_TRACE, "unknown operation"); + return 1; + } + +@@ -226,21 +226,21 @@ cipher_init(struct ssh_cipher_struct *cipher, + + rc = mbedtls_cipher_setup(ctx, cipher_info); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setup failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_setup failed"); + goto error; + } + + key_bitlen = mbedtls_cipher_info_get_key_bitlen(cipher_info); + rc = mbedtls_cipher_setkey(ctx, key, key_bitlen, operation); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_setkey failed"); + goto error; + } + + iv_size = mbedtls_cipher_info_get_iv_size(cipher_info); + rc = mbedtls_cipher_set_iv(ctx, IV, iv_size); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_iv failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_set_iv failed"); + goto error; + } + +@@ -259,13 +259,13 @@ cipher_set_encrypt_key(struct ssh_cipher_struct *cipher, + + rc = cipher_init(cipher, MBEDTLS_ENCRYPT, key, IV); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "cipher_init failed"); ++ SSH_LOG(SSH_LOG_TRACE, "cipher_init failed"); + goto error; + } + + rc = mbedtls_cipher_reset(&cipher->encrypt_ctx); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_reset failed"); + goto error; + } + +@@ -283,7 +283,7 @@ cipher_set_encrypt_key_cbc(struct ssh_cipher_struct *cipher, + + rc = cipher_init(cipher, MBEDTLS_ENCRYPT, key, IV); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "cipher_init failed"); ++ SSH_LOG(SSH_LOG_TRACE, "cipher_init failed"); + goto error; + } + +@@ -293,13 +293,13 @@ cipher_set_encrypt_key_cbc(struct ssh_cipher_struct *cipher, + MBEDTLS_PADDING_NONE); + + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_padding_mode failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_set_padding_mode failed"); + goto error; + } + + rc = mbedtls_cipher_reset(&cipher->encrypt_ctx); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_reset failed"); + goto error; + } + +@@ -327,7 +327,7 @@ cipher_set_key_gcm(struct ssh_cipher_struct *cipher, + key, key_bitlen); + + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_gcm_setkey failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_gcm_setkey failed"); + goto error; + } + +@@ -350,13 +350,13 @@ cipher_set_decrypt_key(struct ssh_cipher_struct *cipher, + + rc = cipher_init(cipher, MBEDTLS_DECRYPT, key, IV); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "cipher_init failed"); ++ SSH_LOG(SSH_LOG_TRACE, "cipher_init failed"); + goto error; + } + + mbedtls_cipher_reset(&cipher->decrypt_ctx); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_reset failed"); + goto error; + } + +@@ -375,20 +375,20 @@ cipher_set_decrypt_key_cbc(struct ssh_cipher_struct *cipher, + + rc = cipher_init(cipher, MBEDTLS_DECRYPT, key, IV); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "cipher_init failed"); ++ SSH_LOG(SSH_LOG_TRACE, "cipher_init failed"); + goto error; + } + + rc = mbedtls_cipher_set_padding_mode(&cipher->decrypt_ctx, + MBEDTLS_PADDING_NONE); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_padding_mode failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_set_padding_mode failed"); + goto error; + } + + mbedtls_cipher_reset(&cipher->decrypt_ctx); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_reset failed"); + goto error; + } + +@@ -408,7 +408,7 @@ static void cipher_encrypt(struct ssh_cipher_struct *cipher, + int rc = 0; + rc = mbedtls_cipher_update(&cipher->encrypt_ctx, in, len, out, &outlen); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update failed during encryption"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_update failed during encryption"); + return; + } + +@@ -424,7 +424,7 @@ static void cipher_encrypt(struct ssh_cipher_struct *cipher, + total_len += outlen; + + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_finish failed during encryption"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_finish failed during encryption"); + return; + } + +@@ -443,7 +443,7 @@ static void cipher_encrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void + int rc = 0; + rc = mbedtls_cipher_update(&cipher->encrypt_ctx, in, len, out, &outlen); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update failed during encryption"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_update failed during encryption"); + return; + } + +@@ -466,7 +466,7 @@ static void cipher_decrypt(struct ssh_cipher_struct *cipher, + + rc = mbedtls_cipher_update(&cipher->decrypt_ctx, in, len, out, &outlen); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update failed during decryption"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_update failed during decryption"); + return; + } + +@@ -480,7 +480,7 @@ static void cipher_decrypt(struct ssh_cipher_struct *cipher, + outlen, &outlen); + + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed during decryption"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_reset failed during decryption"); + return; + } + +@@ -501,7 +501,7 @@ static void cipher_decrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void + int rc = 0; + rc = mbedtls_cipher_update(&cipher->decrypt_ctx, in, len, out, &outlen); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update failed during decryption"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_update failed during decryption"); + return; + } + +@@ -520,14 +520,14 @@ static void cipher_decrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void + } + + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_finish failed during decryption"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_finish failed during decryption"); + return; + } + + rc = mbedtls_cipher_reset(&cipher->decrypt_ctx); + + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed during decryption"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_cipher_reset failed during decryption"); + return; + } + +@@ -586,7 +586,7 @@ cipher_encrypt_gcm(struct ssh_cipher_struct *cipher, + authlen, + tag); /* tag */ + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_gcm_crypt_and_tag failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_gcm_crypt_and_tag failed"); + return; + } + +@@ -620,7 +620,7 @@ cipher_decrypt_gcm(struct ssh_cipher_struct *cipher, + (const uint8_t *)complete_packet + aadlen, /* input */ + (unsigned char *)out); /* output */ + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_gcm_auth_decrypt failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_gcm_auth_decrypt failed"); + return SSH_ERROR; + } + +@@ -694,14 +694,14 @@ chacha20_poly1305_set_key(struct ssh_cipher_struct *cipher, + /* K2 uses the first half of the key */ + rv = mbedtls_chacha20_setkey(&ctx->main_ctx, u8key); + if (rv != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_chacha20_setkey(main_ctx) failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_chacha20_setkey(main_ctx) failed"); + goto out; + } + + /* K1 uses the second half of the key */ + rv = mbedtls_chacha20_setkey(&ctx->header_ctx, u8key + CHACHA20_KEYLEN); + if (rv != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_chacha20_setkey(header_ctx) failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_chacha20_setkey(header_ctx) failed"); + goto out; + } + +@@ -734,13 +734,13 @@ chacha20_poly1305_set_iv(struct ssh_cipher_struct *cipher, + + ret = mbedtls_chacha20_starts(&ctx->header_ctx, seqbuf, 0); + if (ret != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_chacha20_starts(header_ctx) failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_chacha20_starts(header_ctx) failed"); + return SSH_ERROR; + } + + ret = mbedtls_chacha20_starts(&ctx->main_ctx, seqbuf, 0); + if (ret != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_chacha20_starts(main_ctx) failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_chacha20_starts(main_ctx) failed"); + return SSH_ERROR; + } + +@@ -769,7 +769,7 @@ chacha20_poly1305_packet_setup(struct ssh_cipher_struct *cipher, + rv = mbedtls_chacha20_update(&ctx->main_ctx, sizeof(zero_block), + zero_block, poly_key); + if (rv != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_chacha20_update failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_chacha20_update failed"); + goto out; + } + #ifdef DEBUG_CRYPTO +@@ -779,7 +779,7 @@ chacha20_poly1305_packet_setup(struct ssh_cipher_struct *cipher, + /* Set the Poly1305 key */ + rv = mbedtls_poly1305_starts(&ctx->poly_ctx, poly_key); + if (rv != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_poly1305_starts failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_poly1305_starts failed"); + goto out; + } + +@@ -815,7 +815,7 @@ chacha20_poly1305_aead_decrypt_length(struct ssh_cipher_struct *cipher, + + rv = mbedtls_chacha20_update(&ctx->header_ctx, sizeof(uint32_t), in, out); + if (rv != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_chacha20_update failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_chacha20_update failed"); + return SSH_ERROR; + } + +@@ -843,7 +843,7 @@ chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + /* Prepare the Poly1305 key */ + rv = chacha20_poly1305_packet_setup(cipher, seq, 0); + if (rv != SSH_OK) { +- SSH_LOG(SSH_LOG_WARNING, "Failed to setup packet"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to setup packet"); + goto out; + } + +@@ -855,13 +855,13 @@ chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + rv = mbedtls_poly1305_update(&ctx->poly_ctx, complete_packet, + encrypted_size + sizeof(uint32_t)); + if (rv != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_poly1305_update failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_poly1305_update failed"); + goto out; + } + + rv = mbedtls_poly1305_finish(&ctx->poly_ctx, tag); + if (rv != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_poly1305_finish failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_poly1305_finish failed"); + goto out; + } + +@@ -882,7 +882,7 @@ chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher, + (uint8_t *)complete_packet + sizeof(uint32_t), + out); + if (rv != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_chacha20_update failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_chacha20_update failed"); + goto out; + } + +@@ -906,7 +906,7 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + /* Prepare the Poly1305 key */ + ret = chacha20_poly1305_packet_setup(cipher, seq, 1); + if (ret != SSH_OK) { +- SSH_LOG(SSH_LOG_WARNING, "Failed to setup packet"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to setup packet"); + return; + } + +@@ -919,7 +919,7 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + (unsigned char *)&in_packet->length, + (unsigned char *)&out_packet->length); + if (ret != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_chacha20_update failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_chacha20_update failed"); + return; + } + #ifdef DEBUG_CRYPTO +@@ -932,19 +932,19 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher, + ret = mbedtls_chacha20_update(&ctx->main_ctx, len - sizeof(uint32_t), + in_packet->payload, out_packet->payload); + if (ret != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_chacha20_update failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_chacha20_update failed"); + return; + } + + /* step 4, compute the MAC */ + ret = mbedtls_poly1305_update(&ctx->poly_ctx, (const unsigned char *)out_packet, len); + if (ret != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_poly1305_update failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_poly1305_update failed"); + return; + } + ret = mbedtls_poly1305_finish(&ctx->poly_ctx, tag); + if (ret != 0) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_poly1305_finish failed"); ++ SSH_LOG(SSH_LOG_TRACE, "mbedtls_poly1305_finish failed"); + return; + } + } +diff --git a/src/messages.c b/src/messages.c +index ff199f96..8d05e248 100644 +--- a/src/messages.c ++++ b/src/messages.c +@@ -160,7 +160,7 @@ static int ssh_execute_server_request(ssh_session session, ssh_message msg) + if (channel != NULL) { + rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_TRACE, + "Failed to send reply for accepting a channel " + "open"); + } +@@ -237,7 +237,7 @@ static int ssh_execute_server_request(ssh_session session, ssh_message msg) + msg->channel_request.pxwidth, + msg->channel_request.pxheight); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_TRACE, + "Failed to iterate callbacks for window change"); + } + return SSH_OK; +@@ -775,7 +775,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){ + + cmp = strcmp(service, "ssh-connection"); + if (cmp != 0) { +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_TRACE, + "Invalid service request: %s", + service); + goto end; +@@ -1612,7 +1612,7 @@ reply_with_failure: + error: + SAFE_FREE(msg); + SAFE_FREE(request); +- SSH_LOG(SSH_LOG_WARNING, "Invalid SSH_MSG_GLOBAL_REQUEST packet"); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid SSH_MSG_GLOBAL_REQUEST packet"); + return rc; + } + +diff --git a/src/misc.c b/src/misc.c +index 3f2652d4..a70ccd04 100644 +--- a/src/misc.c ++++ b/src/misc.c +@@ -1642,20 +1642,20 @@ int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len) + enum ssh_quote_state_e state = NO_QUOTE; + + if (file_name == NULL || buf == NULL || buf_len == 0) { +- SSH_LOG(SSH_LOG_WARNING, "Invalid parameter"); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid parameter"); + return SSH_ERROR; + } + + /* Only allow file names smaller than 32kb. */ + if (strlen(file_name) > 32 * 1024) { +- SSH_LOG(SSH_LOG_WARNING, "File name too long"); ++ SSH_LOG(SSH_LOG_TRACE, "File name too long"); + return SSH_ERROR; + } + + /* Paranoia check */ + required_buf_len = (size_t)3 * strlen(file_name) + 1; + if (required_buf_len > buf_len) { +- SSH_LOG(SSH_LOG_WARNING, "Buffer too small"); ++ SSH_LOG(SSH_LOG_TRACE, "Buffer too small"); + return SSH_ERROR; + } + +@@ -1813,7 +1813,7 @@ int ssh_newline_vis(const char *string, char *buf, size_t buf_len) + } + + if ((2 * strlen(string) + 1) > buf_len) { +- SSH_LOG(SSH_LOG_WARNING, "Buffer too small"); ++ SSH_LOG(SSH_LOG_TRACE, "Buffer too small"); + return SSH_ERROR; + } + +diff --git a/src/packet.c b/src/packet.c +index e01351aa..ab0e1a4c 100644 +--- a/src/packet.c ++++ b/src/packet.c +@@ -1543,7 +1543,7 @@ SSH_PACKET_CALLBACK(ssh_packet_unimplemented){ + + rc = ssh_buffer_unpack(packet, "d", &seq); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_TRACE, + "Could not unpack SSH_MSG_UNIMPLEMENTED packet"); + } + +@@ -1895,7 +1895,7 @@ ssh_packet_set_newkeys(ssh_session session, + session->next_crypto->used |= direction; + if (session->current_crypto != NULL) { + if (session->current_crypto->used & direction) { +- SSH_LOG(SSH_LOG_WARNING, "This direction isn't used anymore."); ++ SSH_LOG(SSH_LOG_TRACE, "This direction isn't used anymore."); + } + /* Mark the current requested direction unused */ + session->current_crypto->used &= ~direction; +diff --git a/src/pki.c b/src/pki.c +index 8f62ce2b..b109cc96 100644 +--- a/src/pki.c ++++ b/src/pki.c +@@ -344,7 +344,7 @@ enum ssh_digest_e ssh_key_hash_from_name(const char *name) + return SSH_DIGEST_AUTO; + } + +- SSH_LOG(SSH_LOG_WARN, "Unknown signature name %s", name); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown signature name %s", name); + + /* TODO we should rather fail */ + return SSH_DIGEST_AUTO; +@@ -376,13 +376,13 @@ int ssh_key_algorithm_allowed(ssh_session session, const char *type) + else if (session->server) { + allowed_list = session->opts.wanted_methods[SSH_HOSTKEYS]; + if (allowed_list == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Session invalid: no host key available"); ++ SSH_LOG(SSH_LOG_TRACE, "Session invalid: no host key available"); + return 0; + } + } + #endif /* WITH_SERVER */ + else { +- SSH_LOG(SSH_LOG_WARN, "Session invalid: not set as client nor server"); ++ SSH_LOG(SSH_LOG_TRACE, "Session invalid: not set as client nor server"); + return 0; + } + +@@ -488,7 +488,7 @@ enum ssh_digest_e ssh_key_type_to_hash(ssh_session session, + case SSH_KEYTYPE_ECDSA: + case SSH_KEYTYPE_UNKNOWN: + default: +- SSH_LOG(SSH_LOG_WARN, "Digest algorithm to be used with key type %u " ++ SSH_LOG(SSH_LOG_TRACE, "Digest algorithm to be used with key type %u " + "is not defined", type); + } + +@@ -954,7 +954,7 @@ int ssh_pki_import_privkey_file(const char *filename, + + file = fopen(filename, "rb"); + if (file == NULL) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Error opening %s: %s", + filename, + ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); +@@ -964,7 +964,7 @@ int ssh_pki_import_privkey_file(const char *filename, + rc = fstat(fileno(file), &sb); + if (rc < 0) { + fclose(file); +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Error getting stat of %s: %s", + filename, + ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); +@@ -978,7 +978,7 @@ int ssh_pki_import_privkey_file(const char *filename, + } + + if (sb.st_size > MAX_PRIVKEY_SIZE) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Private key is bigger than 4M."); + fclose(file); + return SSH_ERROR; +@@ -987,7 +987,7 @@ int ssh_pki_import_privkey_file(const char *filename, + key_buf = malloc(sb.st_size + 1); + if (key_buf == NULL) { + fclose(file); +- SSH_LOG(SSH_LOG_WARN, "Out of memory!"); ++ SSH_LOG(SSH_LOG_TRACE, "Out of memory!"); + return SSH_ERROR; + } + +@@ -996,7 +996,7 @@ int ssh_pki_import_privkey_file(const char *filename, + + if (size != sb.st_size) { + SAFE_FREE(key_buf); +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Error reading %s: %s", + filename, + ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); +@@ -1169,7 +1169,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, + rc = ssh_buffer_unpack(buffer, "SSSSS", &p, &q, &g, + &pubkey, &privkey); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, "Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "Unpack error"); + goto fail; + } + +@@ -1210,7 +1210,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, + rc = ssh_buffer_unpack(buffer, "SSSSSS", &n, &e, &d, + &iqmp, &p, &q); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, "Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "Unpack error"); + goto fail; + } + +@@ -1237,7 +1237,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, + ssh_string_burn(q); + SSH_STRING_FREE(q); + if (rc == SSH_ERROR) { +- SSH_LOG(SSH_LOG_WARN, "Failed to build RSA private key"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to build RSA private key"); + goto fail; + } + } +@@ -1254,7 +1254,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, + + rc = ssh_buffer_unpack(buffer, "SSS", &i, &e, &exp); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, "Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "Unpack error"); + goto fail; + } + +@@ -1274,7 +1274,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, + ssh_string_burn(exp); + SSH_STRING_FREE(exp); + if (rc < 0) { +- SSH_LOG(SSH_LOG_WARN, "Failed to build ECDSA private key"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to build ECDSA private key"); + goto fail; + } + } +@@ -1286,7 +1286,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, + + rc = ssh_buffer_unpack(buffer, "SS", &pubkey, &privkey); + if (rc != SSH_OK){ +- SSH_LOG(SSH_LOG_WARN, "Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "Unpack error"); + goto fail; + } + +@@ -1295,7 +1295,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, + SSH_STRING_FREE(privkey); + SSH_STRING_FREE(pubkey); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, "Failed to build ed25519 key"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to build ed25519 key"); + goto fail; + } + } +@@ -1313,7 +1313,7 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, + case SSH_KEYTYPE_RSA1: + case SSH_KEYTYPE_UNKNOWN: + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown private key type (%d)", type); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown private key type (%d)", type); + goto fail; + } + +@@ -1351,7 +1351,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + + rc = ssh_buffer_unpack(buffer, "SSSS", &p, &q, &g, &pubkey); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, "Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "Unpack error"); + goto fail; + } + +@@ -1370,7 +1370,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + ssh_string_burn(pubkey); + SSH_STRING_FREE(pubkey); + if (rc == SSH_ERROR) { +- SSH_LOG(SSH_LOG_WARN, "Failed to build DSA public key"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to build DSA public key"); + goto fail; + } + } +@@ -1382,7 +1382,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + + rc = ssh_buffer_unpack(buffer, "SS", &e, &n); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, "Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "Unpack error"); + goto fail; + } + +@@ -1396,7 +1396,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + ssh_string_burn(n); + SSH_STRING_FREE(n); + if (rc == SSH_ERROR) { +- SSH_LOG(SSH_LOG_WARN, "Failed to build RSA public key"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to build RSA public key"); + goto fail; + } + } +@@ -1414,7 +1414,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + + rc = ssh_buffer_unpack(buffer, "SS", &i, &e); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, "Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "Unpack error"); + goto fail; + } + +@@ -1430,7 +1430,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + ssh_string_burn(e); + SSH_STRING_FREE(e); + if (rc < 0) { +- SSH_LOG(SSH_LOG_WARN, "Failed to build ECDSA public key"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to build ECDSA public key"); + goto fail; + } + +@@ -1443,7 +1443,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + if (type == SSH_KEYTYPE_SK_ECDSA) { + ssh_string application = ssh_buffer_get_ssh_string(buffer); + if (application == NULL) { +- SSH_LOG(SSH_LOG_WARN, "SK Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "SK Unpack error"); + goto fail; + } + key->sk_application = application; +@@ -1458,7 +1458,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + ssh_string pubkey = ssh_buffer_get_ssh_string(buffer); + + if (ssh_string_len(pubkey) != ED25519_KEY_LEN) { +- SSH_LOG(SSH_LOG_WARN, "Invalid public key length"); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid public key length"); + ssh_string_burn(pubkey); + SSH_STRING_FREE(pubkey); + goto fail; +@@ -1478,7 +1478,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + if (type == SSH_KEYTYPE_SK_ED25519) { + ssh_string application = ssh_buffer_get_ssh_string(buffer); + if (application == NULL) { +- SSH_LOG(SSH_LOG_WARN, "SK Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "SK Unpack error"); + goto fail; + } + key->sk_application = application; +@@ -1496,7 +1496,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, + case SSH_KEYTYPE_RSA1: + case SSH_KEYTYPE_UNKNOWN: + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown public key protocol %d", type); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown public key protocol %d", type); + goto fail; + } + +@@ -1674,26 +1674,26 @@ int ssh_pki_import_pubkey_blob(const ssh_string key_blob, + + buffer = ssh_buffer_new(); + if (buffer == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Out of memory!"); ++ SSH_LOG(SSH_LOG_TRACE, "Out of memory!"); + return SSH_ERROR; + } + + rc = ssh_buffer_add_data(buffer, ssh_string_data(key_blob), + ssh_string_len(key_blob)); + if (rc < 0) { +- SSH_LOG(SSH_LOG_WARN, "Out of memory!"); ++ SSH_LOG(SSH_LOG_TRACE, "Out of memory!"); + goto fail; + } + + type_s = ssh_buffer_get_ssh_string(buffer); + if (type_s == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Out of memory!"); ++ SSH_LOG(SSH_LOG_TRACE, "Out of memory!"); + goto fail; + } + + type = ssh_key_type_from_name(ssh_string_get_char(type_s)); + if (type == SSH_KEYTYPE_UNKNOWN) { +- SSH_LOG(SSH_LOG_WARN, "Unknown key type found!"); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown key type found!"); + goto fail; + } + SSH_STRING_FREE(type_s); +@@ -1797,7 +1797,7 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) + + file = fopen(filename, "rb"); + if (file == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Error opening %s: %s", ++ SSH_LOG(SSH_LOG_TRACE, "Error opening %s: %s", + filename, ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); + return SSH_EOF; + } +@@ -1805,7 +1805,7 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) + rc = fstat(fileno(file), &sb); + if (rc < 0) { + fclose(file); +- SSH_LOG(SSH_LOG_WARN, "Error gettint stat of %s: %s", ++ SSH_LOG(SSH_LOG_TRACE, "Error gettint stat of %s: %s", + filename, ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); + switch (errno) { + case ENOENT: +@@ -1823,7 +1823,7 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) + key_buf = malloc(sb.st_size + 1); + if (key_buf == NULL) { + fclose(file); +- SSH_LOG(SSH_LOG_WARN, "Out of memory!"); ++ SSH_LOG(SSH_LOG_TRACE, "Out of memory!"); + return SSH_ERROR; + } + +@@ -1832,8 +1832,8 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) + + if (size != sb.st_size) { + SAFE_FREE(key_buf); +- SSH_LOG(SSH_LOG_WARN, "Error reading %s: %s", +- filename, ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); ++ SSH_LOG(SSH_LOG_TRACE, "Error reading %s: %s", ++ filename, ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); + return SSH_ERROR; + } + key_buf[size] = '\0'; +@@ -1845,7 +1845,7 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) + *pkey = ssh_pki_openssh_pubkey_import(key_buf); + SAFE_FREE(key_buf); + if (*pkey == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Failed to import public key from OpenSSH" ++ SSH_LOG(SSH_LOG_TRACE, "Failed to import public key from OpenSSH" + " private key file"); + return SSH_ERROR; + } +@@ -2404,7 +2404,7 @@ int pki_key_check_hash_compatible(ssh_key key, + case SSH_KEYTYPE_DSS: + if (hash_type == SSH_DIGEST_SHA1) { + if (ssh_fips_mode()) { +- SSH_LOG(SSH_LOG_WARN, "SHA1 is not allowed in FIPS mode"); ++ SSH_LOG(SSH_LOG_TRACE, "SHA1 is not allowed in FIPS mode"); + return SSH_ERROR; + } else { + return SSH_OK; +@@ -2415,7 +2415,7 @@ int pki_key_check_hash_compatible(ssh_key key, + case SSH_KEYTYPE_RSA: + if (hash_type == SSH_DIGEST_SHA1) { + if (ssh_fips_mode()) { +- SSH_LOG(SSH_LOG_WARN, "SHA1 is not allowed in FIPS mode"); ++ SSH_LOG(SSH_LOG_TRACE, "SHA1 is not allowed in FIPS mode"); + return SSH_ERROR; + } else { + return SSH_OK; +@@ -2459,11 +2459,11 @@ int pki_key_check_hash_compatible(ssh_key key, + case SSH_KEYTYPE_RSA1: + case SSH_KEYTYPE_ECDSA: + case SSH_KEYTYPE_UNKNOWN: +- SSH_LOG(SSH_LOG_WARN, "Unknown key type %d", key->type); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown key type %d", key->type); + return SSH_ERROR; + } + +- SSH_LOG(SSH_LOG_WARN, "Key type %d incompatible with hash type %d", ++ SSH_LOG(SSH_LOG_TRACE, "Key type %d incompatible with hash type %d", + key->type, hash_type); + + return SSH_ERROR; +@@ -2491,7 +2491,7 @@ int ssh_pki_signature_verify(ssh_session session, + sig->type_c); + + if (key_type != sig->type) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Can not verify %s signature with %s key", + sig->type_c, key->type_c); + return SSH_ERROR; +@@ -2522,7 +2522,7 @@ int ssh_pki_signature_verify(ssh_session session, + + ctx = sha256_init(); + if (ctx == NULL) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Can not create SHA256CTX for application hash"); + return SSH_ERROR; + } +@@ -2532,7 +2532,7 @@ int ssh_pki_signature_verify(ssh_session session, + + ctx = sha256_init(); + if (ctx == NULL) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Can not create SHA256CTX for input hash"); + return SSH_ERROR; + } +diff --git a/src/pki_container_openssh.c b/src/pki_container_openssh.c +index cc97da7f..d78800fd 100644 +--- a/src/pki_container_openssh.c ++++ b/src/pki_container_openssh.c +@@ -69,20 +69,20 @@ static int pki_openssh_import_privkey_blob(ssh_buffer key_blob_buffer, + + rc = ssh_buffer_unpack(key_blob_buffer, "s", &type_s); + if (rc == SSH_ERROR){ +- SSH_LOG(SSH_LOG_WARN, "Unpack error"); ++ SSH_LOG(SSH_LOG_TRACE, "Unpack error"); + return SSH_ERROR; + } + + type = ssh_key_type_from_name(type_s); + if (type == SSH_KEYTYPE_UNKNOWN) { +- SSH_LOG(SSH_LOG_WARN, "Unknown key type '%s' found!", type_s); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown key type '%s' found!", type_s); + return SSH_ERROR; + } + SAFE_FREE(type_s); + + rc = pki_import_privkey_buffer(type, key_blob_buffer, &key); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, "Failed to read key in OpenSSH format"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to read key in OpenSSH format"); + goto fail; + } + +@@ -133,17 +133,17 @@ static int pki_private_key_decrypt(ssh_string blob, + } + + if (ciphers[i].name == NULL){ +- SSH_LOG(SSH_LOG_WARN, "Unsupported cipher %s", ciphername); ++ SSH_LOG(SSH_LOG_TRACE, "Unsupported cipher %s", ciphername); + return SSH_ERROR; + } + + cmp = strcmp(kdfname, "bcrypt"); + if (cmp != 0) { +- SSH_LOG(SSH_LOG_WARN, "Unsupported KDF %s", kdfname); ++ SSH_LOG(SSH_LOG_TRACE, "Unsupported KDF %s", kdfname); + return SSH_ERROR; + } + if (ssh_string_len(blob) % cipher.blocksize != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Encrypted string not multiple of blocksize: %zu", + ssh_string_len(blob)); + return SSH_ERROR; +@@ -167,7 +167,7 @@ static int pki_private_key_decrypt(ssh_string blob, + /* We need material for key (keysize bits / 8) and IV (blocksize) */ + key_material_len = cipher.keysize/8 + cipher.blocksize; + if (key_material_len > sizeof(key_material)) { +- SSH_LOG(SSH_LOG_WARN, "Key material too big"); ++ SSH_LOG(SSH_LOG_TRACE, "Key material too big"); + return SSH_ERROR; + } + +@@ -181,7 +181,7 @@ static int pki_private_key_decrypt(ssh_string blob, + if (passphrase == NULL) { + if (auth_fn == NULL) { + SAFE_FREE(salt); +- SSH_LOG(SSH_LOG_WARN, "No passphrase provided"); ++ SSH_LOG(SSH_LOG_TRACE, "No passphrase provided"); + return SSH_ERROR; + } + rc = auth_fn("Passphrase", +@@ -251,7 +251,7 @@ ssh_pki_openssh_import(const char *text_key, + + cmp = strncmp(ptr, OPENSSH_HEADER_BEGIN, strlen(OPENSSH_HEADER_BEGIN)); + if (cmp != 0) { +- SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (no header)"); ++ SSH_LOG(SSH_LOG_TRACE, "Not an OpenSSH private key (no header)"); + goto out; + } + ptr += strlen(OPENSSH_HEADER_BEGIN); +@@ -260,7 +260,7 @@ ssh_pki_openssh_import(const char *text_key, + } + end = strstr(ptr, OPENSSH_HEADER_END); + if (end == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (no footer)"); ++ SSH_LOG(SSH_LOG_TRACE, "Not an OpenSSH private key (no footer)"); + goto out; + } + base64 = malloc(end - ptr + 1); +@@ -277,7 +277,7 @@ ssh_pki_openssh_import(const char *text_key, + buffer = base64_to_bin(base64); + SAFE_FREE(base64); + if (buffer == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (base64 error)"); ++ SSH_LOG(SSH_LOG_TRACE, "Not an OpenSSH private key (base64 error)"); + goto out; + } + rc = ssh_buffer_unpack(buffer, "PssSdSS", +@@ -290,12 +290,12 @@ ssh_pki_openssh_import(const char *text_key, + &pubkey0, + &privkeys); + if (rc == SSH_ERROR) { +- SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (unpack error)"); ++ SSH_LOG(SSH_LOG_TRACE, "Not an OpenSSH private key (unpack error)"); + goto out; + } + cmp = strncmp(magic, OPENSSH_AUTH_MAGIC, strlen(OPENSSH_AUTH_MAGIC)); + if (cmp != 0) { +- SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (bad magic)"); ++ SSH_LOG(SSH_LOG_TRACE, "Not an OpenSSH private key (bad magic)"); + goto out; + } + SSH_LOG(SSH_LOG_INFO, +@@ -304,7 +304,7 @@ ssh_pki_openssh_import(const char *text_key, + kdfname, + nkeys); + if (nkeys != 1) { +- SSH_LOG(SSH_LOG_WARN, "Opening OpenSSH private key: only 1 key supported (%d available)", nkeys); ++ SSH_LOG(SSH_LOG_TRACE, "Opening OpenSSH private key: only 1 key supported (%d available)", nkeys); + goto out; + } + +@@ -314,7 +314,7 @@ ssh_pki_openssh_import(const char *text_key, + if (!private) { + rc = ssh_pki_import_pubkey_blob(pubkey0, &key); + if (rc != SSH_OK) { +- SSH_LOG(SSH_LOG_WARN, "Failed to import public key blob"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to import public key blob"); + } + /* in either case we clean up here */ + goto out; +@@ -343,7 +343,7 @@ ssh_pki_openssh_import(const char *text_key, + + rc = ssh_buffer_unpack(privkey_buffer, "dd", &checkint1, &checkint2); + if (rc == SSH_ERROR || checkint1 != checkint2) { +- SSH_LOG(SSH_LOG_WARN, "OpenSSH private key unpack error (correct password?)"); ++ SSH_LOG(SSH_LOG_TRACE, "OpenSSH private key unpack error (correct password?)"); + goto out; + } + rc = pki_openssh_import_privkey_blob(privkey_buffer, &key); +@@ -358,7 +358,7 @@ ssh_pki_openssh_import(const char *text_key, + if (padding != i) { + ssh_key_free(key); + key = NULL; +- SSH_LOG(SSH_LOG_WARN, "Invalid padding"); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid padding"); + goto out; + } + } +@@ -407,7 +407,7 @@ static int pki_openssh_export_privkey_blob(const ssh_key privkey, + int rc; + + if (privkey->type != SSH_KEYTYPE_ED25519) { +- SSH_LOG(SSH_LOG_WARN, "Type %s not supported", privkey->type_c); ++ SSH_LOG(SSH_LOG_TRACE, "Type %s not supported", privkey->type_c); + return SSH_ERROR; + } + if (privkey->ed25519_privkey == NULL || +@@ -462,19 +462,19 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer, + } + + if (ciphers[i].name == NULL){ +- SSH_LOG(SSH_LOG_WARN, "Unsupported cipher %s", ciphername); ++ SSH_LOG(SSH_LOG_TRACE, "Unsupported cipher %s", ciphername); + return SSH_ERROR; + } + + cmp = strcmp(kdfname, "bcrypt"); + if (cmp != 0){ +- SSH_LOG(SSH_LOG_WARN, "Unsupported KDF %s", kdfname); ++ SSH_LOG(SSH_LOG_TRACE, "Unsupported KDF %s", kdfname); + return SSH_ERROR; + } + /* We need material for key (keysize bits / 8) and IV (blocksize) */ + key_material_len = cipher.keysize/8 + cipher.blocksize; + if (key_material_len > sizeof(key_material)){ +- SSH_LOG(SSH_LOG_WARN, "Key material too big"); ++ SSH_LOG(SSH_LOG_TRACE, "Key material too big"); + return SSH_ERROR; + } + +@@ -484,7 +484,7 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer, + + if (passphrase == NULL){ + if (auth_fn == NULL){ +- SSH_LOG(SSH_LOG_WARN, "No passphrase provided"); ++ SSH_LOG(SSH_LOG_TRACE, "No passphrase provided"); + return SSH_ERROR; + } + rc = auth_fn("Passphrase", +@@ -555,7 +555,7 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey, + return NULL; + } + if (privkey->type != SSH_KEYTYPE_ED25519){ +- SSH_LOG(SSH_LOG_WARN, "Unsupported key type %s", privkey->type_c); ++ SSH_LOG(SSH_LOG_TRACE, "Unsupported key type %s", privkey->type_c); + return NULL; + } + if (passphrase != NULL || auth_fn != NULL){ +diff --git a/src/pki_crypto.c b/src/pki_crypto.c +index 33544d6a..0a5003da 100644 +--- a/src/pki_crypto.c ++++ b/src/pki_crypto.c +@@ -916,7 +916,7 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter) { + #endif /* OPENSSL_VERSION_NUMBER */ + break; + default: +- SSH_LOG(SSH_LOG_WARN, "Invalid parameter %d for ECDSA key " ++ SSH_LOG(SSH_LOG_TRACE, "Invalid parameter %d for ECDSA key " + "generation", parameter); + return SSH_ERROR; + } +@@ -1207,7 +1207,7 @@ ssh_string pki_private_key_to_pem(const ssh_key key, + rc = 1; + break; + #else +- SSH_LOG(SSH_LOG_WARN, "PEM output not supported for key type ssh-ed25519"); ++ SSH_LOG(SSH_LOG_TRACE, "PEM output not supported for key type ssh-ed25519"); + goto err; + #endif /* HAVE_OPENSSL_ED25519 */ + case SSH_KEYTYPE_DSS_CERT01: +@@ -1218,11 +1218,11 @@ ssh_string pki_private_key_to_pem(const ssh_key key, + case SSH_KEYTYPE_ED25519_CERT01: + case SSH_KEYTYPE_UNKNOWN: + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", key->type); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown or invalid private key type %d", key->type); + goto err; + } + if (rc != 1) { +- SSH_LOG(SSH_LOG_WARN, "Failed to initialize EVP_PKEY structure"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to initialize EVP_PKEY structure"); + goto err; + } + +@@ -1317,8 +1317,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + BIO_free(mem); + + if (pkey == NULL) { +- SSH_LOG(SSH_LOG_WARN, +- "Parsing private key: %s", ++ SSH_LOG(SSH_LOG_TRACE, ++ "Error parsing private key: %s", + ERR_error_string(ERR_get_error(), NULL)); + return NULL; + } +@@ -1327,8 +1327,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + #if OPENSSL_VERSION_NUMBER < 0x30000000L + dsa = EVP_PKEY_get1_DSA(pkey); + if (dsa == NULL) { +- SSH_LOG(SSH_LOG_WARN, +- "Parsing private key: %s", ++ SSH_LOG(SSH_LOG_TRACE, ++ "Error parsing private key: %s", + ERR_error_string(ERR_get_error(),NULL)); + goto fail; + } +@@ -1339,8 +1339,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + #if OPENSSL_VERSION_NUMBER < 0x30000000L + rsa = EVP_PKEY_get1_RSA(pkey); + if (rsa == NULL) { +- SSH_LOG(SSH_LOG_WARN, +- "Parsing private key: %s", ++ SSH_LOG(SSH_LOG_TRACE, ++ "Error parsing private key: %s", + ERR_error_string(ERR_get_error(),NULL)); + goto fail; + } +@@ -1356,8 +1356,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + #if 1 + ecdsa = EVP_PKEY_get1_EC_KEY(pkey); + if (ecdsa == NULL) { +- SSH_LOG(SSH_LOG_WARN, +- "Parsing private key: %s", ++ SSH_LOG(SSH_LOG_TRACE, ++ "Error parsing private key: %s", + ERR_error_string(ERR_get_error(), NULL)); + goto fail; + } +@@ -1375,7 +1375,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + type = pki_key_ecdsa_to_key_type(pkey); + #endif /* OPENSSL_VERSION_NUMBER */ + if (type == SSH_KEYTYPE_UNKNOWN) { +- SSH_LOG(SSH_LOG_WARN, "Invalid private key."); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid private key."); + goto fail; + } + +@@ -1406,7 +1406,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + + ed25519 = malloc(key_len); + if (ed25519 == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Out of memory"); ++ SSH_LOG(SSH_LOG_TRACE, "Out of memory"); + goto fail; + } + +@@ -1424,7 +1424,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + break; + #endif /* HAVE_OPENSSL_ED25519 */ + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", ++ SSH_LOG(SSH_LOG_TRACE, "Unknown or invalid private key type %d", + EVP_PKEY_base_id(pkey)); + EVP_PKEY_free(pkey); + return NULL; +@@ -1856,7 +1856,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + } + out_param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P); + if (out_param == NULL) { +- SSH_LOG(SSH_LOG_WARN, "DSA: No param P has been found"); ++ SSH_LOG(SSH_LOG_TRACE, "DSA: No param P has been found"); + goto fail; + } + rc = OSSL_PARAM_get_BN(out_param, &bp); +@@ -1865,7 +1865,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + } + out_param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q); + if (out_param == NULL) { +- SSH_LOG(SSH_LOG_WARN, "DSA: No param Q has been found"); ++ SSH_LOG(SSH_LOG_TRACE, "DSA: No param Q has been found"); + goto fail; + } + rc = OSSL_PARAM_get_BN(out_param, &bq); +@@ -1874,7 +1874,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + } + out_param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G); + if (out_param == NULL) { +- SSH_LOG(SSH_LOG_WARN, "DSA: No param G has been found"); ++ SSH_LOG(SSH_LOG_TRACE, "DSA: No param G has been found"); + goto fail; + } + rc = OSSL_PARAM_get_BN(out_param, &bg); +@@ -1883,7 +1883,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + } + out_param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); + if (out_param == NULL) { +- SSH_LOG(SSH_LOG_WARN, "DSA: No param PUB_KEY has been found"); ++ SSH_LOG(SSH_LOG_TRACE, "DSA: No param PUB_KEY has been found"); + goto fail; + } + rc = OSSL_PARAM_get_BN(out_param, &bpub_key); +@@ -1959,7 +1959,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + } + out_param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E); + if (out_param == NULL) { +- SSH_LOG(SSH_LOG_WARN, "RSA: No param E has been found"); ++ SSH_LOG(SSH_LOG_TRACE, "RSA: No param E has been found"); + goto fail; + } + rc = OSSL_PARAM_get_BN(out_param, &be); +@@ -1968,7 +1968,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + } + out_param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N); + if (out_param == NULL) { +- SSH_LOG(SSH_LOG_WARN, "RSA: No param N has been found"); ++ SSH_LOG(SSH_LOG_TRACE, "RSA: No param N has been found"); + goto fail; + } + rc = OSSL_PARAM_get_BN(out_param, &bn); +@@ -2053,7 +2053,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + #if 1 + #ifdef WITH_PKCS11_URI + if (ssh_key_is_private(key) && !EC_KEY_get0_public_key(key->ecdsa)) { +- SSH_LOG(SSH_LOG_INFO, "It is mandatory to have separate public" ++ SSH_LOG(SSH_LOG_TRACE, "It is mandatory to have separate public" + " ECDSA key objects in the PKCS #11 device. Unlike RSA," + " ECDSA public keys cannot be derived from their private keys."); + goto fail; +@@ -2078,7 +2078,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) + locate_param = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY); + #ifdef WITH_PKCS11_URI + if (ssh_key_is_private(key) && !locate_param) { +- SSH_LOG(SSH_LOG_INFO, "It is mandatory to have separate" ++ SSH_LOG(SSH_LOG_TRACE, "It is mandatory to have separate" + " public ECDSA key objects in the PKCS #11 device." + " Unlike RSA, ECDSA public keys cannot be derived" + " from their private keys."); +@@ -2386,7 +2386,7 @@ ssh_string pki_signature_to_blob(const ssh_signature sig) + #endif /* HAVE_OPENSSL_ECC */ + default: + case SSH_KEYTYPE_UNKNOWN: +- SSH_LOG(SSH_LOG_WARN, "Unknown signature key type: %s", sig->type_c); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown signature key type: %s", sig->type_c); + return NULL; + } + +@@ -2407,21 +2407,21 @@ static int pki_signature_from_rsa_blob(const ssh_key pubkey, + + #if OPENSSL_VERSION_NUMBER < 0x30000000L + if (pubkey->rsa == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Pubkey RSA field NULL"); ++ SSH_LOG(SSH_LOG_TRACE, "Pubkey RSA field NULL"); + goto errout; + } + + rsalen = RSA_size(pubkey->rsa); + #else + if (EVP_PKEY_get_base_id(pubkey->key) != EVP_PKEY_RSA) { +- SSH_LOG(SSH_LOG_WARN, "Key has no RSA pubkey"); ++ SSH_LOG(SSH_LOG_TRACE, "Key has no RSA pubkey"); + goto errout; + } + + rsalen = EVP_PKEY_size(pubkey->key); + #endif /* OPENSSL_VERSION_NUMBER */ + if (len > rsalen) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Signature is too big: %lu > %lu", + (unsigned long)len, + (unsigned long)rsalen); +@@ -2493,7 +2493,7 @@ static int pki_signature_from_dsa_blob(UNUSED_PARAM(const ssh_key pubkey), + + /* 40 is the dual signature blob len. */ + if (len != 40) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Signature has wrong size: %lu", + (unsigned long)len); + goto error; +@@ -2656,7 +2656,7 @@ static int pki_signature_from_ecdsa_blob(UNUSED_PARAM(const ssh_key pubkey), + if (rlen != 0) { + ssh_string_burn(s); + SSH_STRING_FREE(s); +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Signature has remaining bytes in inner " + "sigblob: %lu", + (unsigned long)rlen); +@@ -2745,7 +2745,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + int rc; + + if (ssh_key_type_plain(pubkey->type) != type) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Incompatible public key provided (%d) expecting (%d)", + type, + pubkey->type); +@@ -2799,7 +2799,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + #endif + default: + case SSH_KEYTYPE_UNKNOWN: +- SSH_LOG(SSH_LOG_WARN, "Unknown signature type"); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown signature type"); + goto error; + } + +@@ -3462,7 +3462,7 @@ int pki_uri_import(const char *uri_name, + /* Do the init only once */ + engine = pki_get_engine(); + if (engine == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Failed to initialize engine"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to initialize engine"); + goto fail; + } + +@@ -3470,7 +3470,7 @@ int pki_uri_import(const char *uri_name, + case SSH_KEY_PRIVATE: + pkey = ENGINE_load_private_key(engine, uri_name, NULL, NULL); + if (pkey == NULL) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Could not load key: %s", + ERR_error_string(ERR_get_error(),NULL)); + goto fail; +@@ -3479,14 +3479,14 @@ int pki_uri_import(const char *uri_name, + case SSH_KEY_PUBLIC: + pkey = ENGINE_load_public_key(engine, uri_name, NULL, NULL); + if (pkey == NULL) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Could not load key: %s", + ERR_error_string(ERR_get_error(),NULL)); + goto fail; + } + break; + default: +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Invalid key type: %d", key_type); + goto fail; + } +@@ -3501,7 +3501,7 @@ int pki_uri_import(const char *uri_name, + #if OPENSSL_VERSION_NUMBER < 0x30000000L + rsa = EVP_PKEY_get1_RSA(pkey); + if (rsa == NULL) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Parsing pub key: %s", + ERR_error_string(ERR_get_error(),NULL)); + goto fail; +@@ -3518,7 +3518,7 @@ int pki_uri_import(const char *uri_name, + #if 1 + ecdsa = EVP_PKEY_get1_EC_KEY(pkey); + if (ecdsa == NULL) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Parsing pub key: %s", + ERR_error_string(ERR_get_error(), NULL)); + goto fail; +@@ -3531,14 +3531,14 @@ int pki_uri_import(const char *uri_name, + type = pki_key_ecdsa_to_key_type(pkey); + #endif /* OPENSSL_VERSION_NUMBER */ + if (type == SSH_KEYTYPE_UNKNOWN) { +- SSH_LOG(SSH_LOG_WARN, "Invalid pub key."); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid pub key."); + goto fail; + } + + break; + #endif + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown or invalid public key type %d", ++ SSH_LOG(SSH_LOG_TRACE, "Unknown or invalid public key type %d", + EVP_PKEY_base_id(pkey)); + goto fail; + } +diff --git a/src/pki_ed25519_common.c b/src/pki_ed25519_common.c +index 7aa05269..15c9abef 100644 +--- a/src/pki_ed25519_common.c ++++ b/src/pki_ed25519_common.c +@@ -34,7 +34,7 @@ int pki_privkey_build_ed25519(ssh_key key, + if (ssh_string_len(pubkey) != ED25519_KEY_LEN || + ssh_string_len(privkey) != (2 * ED25519_KEY_LEN)) + { +- SSH_LOG(SSH_LOG_WARN, "Invalid ed25519 key len"); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid ed25519 key len"); + return SSH_ERROR; + } + +@@ -266,7 +266,7 @@ int pki_signature_from_ed25519_blob(ssh_signature sig, ssh_string sig_blob) + + len = ssh_string_len(sig_blob); + if (len != ED25519_SIG_LEN){ +- SSH_LOG(SSH_LOG_WARN, "Invalid ssh-ed25519 signature len: %zu", len); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid ssh-ed25519 signature len: %zu", len); + return SSH_ERROR; + } + +diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c +index b619b1a3..702b9b2b 100644 +--- a/src/pki_gcrypt.c ++++ b/src/pki_gcrypt.c +@@ -955,7 +955,7 @@ ssh_string pki_private_key_to_pem(const ssh_key key, + (void) auth_fn; + (void) auth_data; + +- SSH_LOG(SSH_LOG_WARN, "PEM export not supported by gcrypt backend!"); ++ SSH_LOG(SSH_LOG_TRACE, "PEM export not supported by gcrypt backend!"); + + return NULL; + } +@@ -974,7 +974,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + + type = pki_privatekey_type_from_string(b64_key); + if (type == SSH_KEYTYPE_UNKNOWN) { +- SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key."); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown or invalid private key."); + return NULL; + } + +@@ -994,7 +994,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + } + + if (!valid) { +- SSH_LOG(SSH_LOG_WARN, "Parsing private key"); ++ SSH_LOG(SSH_LOG_TRACE, "Error parsing private key"); + goto fail; + } + break; +@@ -1013,7 +1013,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + } + + if (!valid) { +- SSH_LOG(SSH_LOG_WARN, "Parsing private key"); ++ SSH_LOG(SSH_LOG_TRACE, "Error parsing private key"); + goto fail; + } + break; +@@ -1044,7 +1044,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + } + + if (!valid) { +- SSH_LOG(SSH_LOG_WARN, "Parsing private key"); ++ SSH_LOG(SSH_LOG_TRACE, "Error parsing private key"); + goto fail; + } + +@@ -1052,7 +1052,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + * keys, so we need to figure out the correct type here */ + type = pki_key_ecdsa_to_key_type(ecdsa); + if (type == SSH_KEYTYPE_UNKNOWN) { +- SSH_LOG(SSH_LOG_WARN, "Invalid private key."); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid private key."); + goto fail; + } + break; +@@ -1062,7 +1062,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, + case SSH_KEYTYPE_RSA1: + case SSH_KEYTYPE_UNKNOWN: + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown or invalid private key type %d", type); + return NULL; + } + +@@ -1938,7 +1938,7 @@ ssh_string pki_signature_to_blob(const ssh_signature sig) + case SSH_KEYTYPE_RSA1: + case SSH_KEYTYPE_UNKNOWN: + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown signature key type: %d", sig->type); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown signature key type: %d", sig->type); + return NULL; + break; + } +@@ -1958,7 +1958,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + int rc; + + if (ssh_key_type_plain(pubkey->type) != type) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Incompatible public key provided (%d) expecting (%d)", + type, + pubkey->type); +@@ -1980,7 +1980,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + case SSH_KEYTYPE_DSS: + /* 40 is the dual signature blob len. */ + if (len != 40) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Signature has wrong size: %lu", + (unsigned long)len); + ssh_signature_free(sig); +@@ -2010,7 +2010,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + rsalen = (gcry_pk_get_nbits(pubkey->rsa) + 7) / 8; + + if (len > rsalen) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Signature is too big: %lu > %lu", + (unsigned long)len, + (unsigned long)rsalen); +@@ -2091,7 +2091,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + } + + if (rlen != 0) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Signature has remaining bytes in inner " + "sigblob: %lu", + (unsigned long)rlen); +@@ -2129,7 +2129,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + case SSH_KEYTYPE_RSA1: + case SSH_KEYTYPE_UNKNOWN: + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown signature type"); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown signature type"); + return NULL; + } + +@@ -2190,7 +2190,7 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey, + break; + case SSH_DIGEST_AUTO: + default: +- SSH_LOG(SSH_LOG_WARN, "Incompatible key algorithm"); ++ SSH_LOG(SSH_LOG_TRACE, "Incompatible key algorithm"); + return NULL; + } + err = gcry_sexp_build(&sexp, +@@ -2548,7 +2548,7 @@ int pki_uri_import(const char *uri_name, ssh_key *key, enum ssh_key_e key_type) + (void) uri_name; + (void) key; + (void) key_type; +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "gcrypt does not support PKCS #11"); + return SSH_ERROR; + } +diff --git a/src/pki_mbedcrypto.c b/src/pki_mbedcrypto.c +index 4439b3cd..045bad50 100644 +--- a/src/pki_mbedcrypto.c ++++ b/src/pki_mbedcrypto.c +@@ -222,7 +222,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase, + * keys, so we need to figure out the correct type here */ + key->type = pki_key_ecdsa_to_key_type(key->ecdsa); + if (key->type == SSH_KEYTYPE_UNKNOWN) { +- SSH_LOG(SSH_LOG_WARN, "Invalid private key."); ++ SSH_LOG(SSH_LOG_TRACE, "Invalid private key."); + goto fail; + } + break; +@@ -281,19 +281,19 @@ int pki_privkey_build_rsa(ssh_key key, + ssh_string_data(d), ssh_string_len(d), + ssh_string_data(e), ssh_string_len(e)); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, "Failed to import private RSA key"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to import private RSA key"); + goto fail; + } + + rc = mbedtls_rsa_complete(rsa); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, "Failed to complete private RSA key"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to complete private RSA key"); + goto fail; + } + + rc = mbedtls_rsa_check_privkey(rsa); + if (rc != 0) { +- SSH_LOG(SSH_LOG_WARN, "Inconsistent private RSA key"); ++ SSH_LOG(SSH_LOG_TRACE, "Inconsistent private RSA key"); + goto fail; + } + +@@ -1133,7 +1133,7 @@ ssh_string pki_signature_to_blob(const ssh_signature sig) + sig_blob = pki_ed25519_signature_to_blob(sig); + break; + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown signature key type: %s", ++ SSH_LOG(SSH_LOG_TRACE, "Unknown signature key type: %s", + sig->type_c); + return NULL; + } +@@ -1153,20 +1153,20 @@ static ssh_signature pki_signature_from_rsa_blob(const ssh_key pubkey, const + size_t len = ssh_string_len(sig_blob); + + if (pubkey->rsa == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Pubkey RSA field NULL"); ++ SSH_LOG(SSH_LOG_TRACE, "Pubkey RSA field NULL"); + goto errout; + } + + rsalen = mbedtls_pk_get_bitlen(pubkey->rsa) / 8; + if (len > rsalen) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Signature is too big: %lu > %lu", + (unsigned long) len, + (unsigned long) rsalen); + goto errout; + } + #ifdef DEBUG_CRYPTO +- SSH_LOG(SSH_LOG_DEBUG, "RSA signature len: %lu", (unsigned long)len); ++ SSH_LOG(SSH_LOG_TRACE, "RSA signature len: %lu", (unsigned long)len); + ssh_log_hexdump("RSA signature", ssh_string_data(sig_blob), len); + #endif + +@@ -1207,7 +1207,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + int rc; + + if (ssh_key_type_plain(pubkey->type) != type) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_TRACE, + "Incompatible public key provided (%d) expecting (%d)", + type, + pubkey->type); +@@ -1292,7 +1292,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + } + + if (rlen != 0) { +- SSH_LOG(SSH_LOG_WARN, "Signature has remaining bytes in inner " ++ SSH_LOG(SSH_LOG_TRACE, "Signature has remaining bytes in inner " + "sigblob: %lu", + (unsigned long)rlen); + ssh_signature_free(sig); +@@ -1310,7 +1310,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, + } + break; + default: +- SSH_LOG(SSH_LOG_WARN, "Unknown signature type"); ++ SSH_LOG(SSH_LOG_TRACE, "Unknown signature type"); + return NULL; + } + +@@ -1341,7 +1341,7 @@ static ssh_string rsa_do_sign_hash(const unsigned char *digest, + break; + case SSH_DIGEST_AUTO: + default: +- SSH_LOG(SSH_LOG_WARN, "Incompatible key algorithm"); ++ SSH_LOG(SSH_LOG_TRACE, "Incompatible key algorithm"); + return NULL; + } + +diff --git a/src/session.c b/src/session.c +index 6025c133..64e54957 100644 +--- a/src/session.c ++++ b/src/session.c +@@ -1188,8 +1188,8 @@ int ssh_get_publickey_hash(const ssh_key key, + + /* In FIPS mode, we cannot use MD5 */ + if (ssh_fips_mode()) { +- SSH_LOG(SSH_LOG_WARN, "In FIPS mode MD5 is not allowed." +- "Try using SSH_PUBLICKEY_HASH_SHA256"); ++ SSH_LOG(SSH_LOG_TRACE, "In FIPS mode MD5 is not allowed." ++ "Try using SSH_PUBLICKEY_HASH_SHA256"); + rc = SSH_ERROR; + goto out; + } +diff --git a/src/socket.c b/src/socket.c +index 4e637ae1..16c84e0e 100644 +--- a/src/socket.c ++++ b/src/socket.c +@@ -489,13 +489,13 @@ void ssh_socket_close(ssh_socket s) + while (waitpid(pid, &status, 0) == -1) { + if (errno != EINTR) { + char err_msg[SSH_ERRNO_MSG_MAX] = {0}; +- SSH_LOG(SSH_LOG_WARN, "waitpid failed: %s", ++ SSH_LOG(SSH_LOG_TRACE, "waitpid failed: %s", + ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); + return; + } + } + if (!WIFEXITED(status)) { +- SSH_LOG(SSH_LOG_WARN, "Proxy command exited abnormally"); ++ SSH_LOG(SSH_LOG_TRACE, "Proxy command exited abnormally"); + return; + } + SSH_LOG(SSH_LOG_TRACE, "Proxy command returned %d", WEXITSTATUS(status)); +@@ -896,7 +896,7 @@ ssh_execute_command(const char *command, socket_t in, socket_t out) + /* Prepare /dev/null socket for the stderr redirection */ + devnull = open("/dev/null", O_WRONLY); + if (devnull == -1) { +- SSH_LOG(SSH_LOG_WARNING, "Failed to open /dev/null"); ++ SSH_LOG(SSH_LOG_TRACE, "Failed to open /dev/null"); + exit(1); + } + +-- +2.38.1 + + +From eb9152f72ed8fd14f369ac45a8518c8fb8e4b743 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Thu, 15 Sep 2022 20:48:19 +0200 +Subject: [PATCH 3/5] SSH_LOG_DEBUG: Recategorize loglevels + +Loglevel INFO is the default openssh configuration setting which does not print +redundant information. On a system using openssh with loglevels set by the +terms of openssh will cause unwanted log lines in the output. +recategorized based on - SSH_LOG_DEBUG are informational debug logs (no error) + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +Reviewed-by: Andreas Schneider +--- + src/agent.c | 6 +++--- + src/auth.c | 14 +++++++------- + src/bind.c | 2 +- + src/bind_config.c | 4 ++-- + src/channels.c | 26 +++++++++++++------------- + src/client.c | 6 +++--- + src/config.c | 6 +++--- + src/curve25519.c | 6 +++--- + src/dh-gex.c | 16 ++++++++-------- + src/dh.c | 2 +- + src/ecdh.c | 2 +- + src/ecdh_crypto.c | 4 ++-- + src/ecdh_gcrypt.c | 4 ++-- + src/ecdh_mbedcrypto.c | 4 ++-- + src/gssapi.c | 36 ++++++++++++++++++------------------ + src/kex.c | 4 ++-- + src/libcrypto.c | 10 +++++----- + src/libgcrypt.c | 2 +- + src/libmbedcrypto.c | 8 ++++---- + src/messages.c | 16 ++++++++-------- + src/misc.c | 8 ++++---- + src/packet.c | 4 ++-- + src/packet_cb.c | 6 +++--- + src/pki.c | 4 ++-- + src/pki_container_openssh.c | 6 +++--- + src/scp.c | 8 ++++---- + src/server.c | 11 +++++------ + src/sftp.c | 14 +++++++------- + src/socket.c | 6 +++--- + 29 files changed, 122 insertions(+), 123 deletions(-) + +diff --git a/src/agent.c b/src/agent.c +index 59963605..4542f424 100644 +--- a/src/agent.c ++++ b/src/agent.c +@@ -296,12 +296,12 @@ static int agent_talk(struct ssh_session_struct *session, + + payload = ssh_buffer_allocate(reply, len); + if (payload == NULL) { +- SSH_LOG(SSH_LOG_WARN, "Not enough space"); ++ SSH_LOG(SSH_LOG_DEBUG, "Not enough space"); + return -1; + } + + if (atomicio(session->agent, payload, len, 1) != len) { +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_DEBUG, + "Error reading response from authentication socket."); + /* Rollback the unused space */ + ssh_buffer_pass_bytes_end(reply, len); +@@ -577,7 +577,7 @@ ssh_string ssh_agent_sign_data(ssh_session session, + #endif + + if (agent_failed(type)) { +- SSH_LOG(SSH_LOG_WARN, "Agent reports failure in signing the key"); ++ SSH_LOG(SSH_LOG_DEBUG, "Agent reports failure in signing the key"); + SSH_BUFFER_FREE(reply); + return NULL; + } else if (type != SSH2_AGENT_SIGN_RESPONSE) { +diff --git a/src/auth.c b/src/auth.c +index cc8089a1..17376c8f 100644 +--- a/src/auth.c ++++ b/src/auth.c +@@ -240,7 +240,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_failure) { + + if (partial) { + session->auth.state = SSH_AUTH_STATE_PARTIAL; +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_DEBUG, + "Partial success for '%s'. Authentication that can continue: %s", + current_method, + auth_methods); +@@ -250,7 +250,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_failure) { + "Access denied for '%s'. Authentication that can continue: %s", + current_method, + auth_methods); +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_DEBUG, + "%s", + ssh_get_error(session)); + +@@ -975,7 +975,7 @@ int ssh_userauth_agent(ssh_session session, + session->agent_state = NULL; + return rc; + } else if (rc != SSH_AUTH_SUCCESS) { +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_DEBUG, + "Server accepted public key but refused the signature"); + ssh_key_free(state->pubkey); + state->pubkey = ssh_agent_get_next_ident(session, &state->comment); +@@ -1253,7 +1253,7 @@ int ssh_userauth_publickey_auto(ssh_session session, + /* If the file doesn't exist, continue */ + ssh_key_free(state->pubkey); + state->pubkey = NULL; +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_DEBUG, + "Private key %s doesn't exist.", + privkey_file); + state->it = state->it->next; +@@ -1268,7 +1268,7 @@ int ssh_userauth_publickey_auto(ssh_session session, + ssh_key_free(state->pubkey); + SAFE_FREE(session->auth.auto_state); + if (rc == SSH_AUTH_SUCCESS) { +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_DEBUG, + "Successfully authenticated using %s", + privkey_file); + } +@@ -1281,7 +1281,7 @@ int ssh_userauth_publickey_auto(ssh_session session, + ssh_key_free(state->privkey); + ssh_key_free(state->pubkey); + +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_DEBUG, + "The server accepted the public key but refused the signature"); + state->it = state->it->next; + state->state = SSH_AUTH_AUTO_STATE_PUBKEY; +@@ -2031,7 +2031,7 @@ int ssh_userauth_gssapi(ssh_session session) + } else if (rc == SSH_ERROR) { + return SSH_AUTH_ERROR; + } +- SSH_LOG(SSH_LOG_PROTOCOL, "Authenticating with gssapi-with-mic"); ++ SSH_LOG(SSH_LOG_DEBUG, "Authenticating with gssapi-with-mic"); + + session->auth.current_method = SSH_AUTH_METHOD_GSSAPI_MIC; + session->auth.state = SSH_AUTH_STATE_NONE; +diff --git a/src/bind.c b/src/bind.c +index 77acbb66..d947cd78 100644 +--- a/src/bind.c ++++ b/src/bind.c +@@ -297,7 +297,7 @@ int ssh_bind_listen(ssh_bind sshbind) { + + sshbind->bindfd = fd; + } else { +- SSH_LOG(SSH_LOG_INFO, "Using app-provided bind socket"); ++ SSH_LOG(SSH_LOG_DEBUG, "Using app-provided bind socket"); + } + return 0; + } +diff --git a/src/bind_config.c b/src/bind_config.c +index a2f2efe4..a4c7a8d7 100644 +--- a/src/bind_config.c ++++ b/src/bind_config.c +@@ -546,7 +546,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + return -1; + } + args++; +- SSH_LOG(SSH_LOG_WARN, ++ SSH_LOG(SSH_LOG_DEBUG, + "line %d: Unsupported Match keyword '%s', ignoring\n", + count, + p2); +@@ -595,7 +595,7 @@ ssh_bind_config_parse_line(ssh_bind bind, + } + break; + case BIND_CFG_NOT_ALLOWED_IN_MATCH: +- SSH_LOG(SSH_LOG_WARN, "Option not allowed in Match block: %s, line: %d", ++ SSH_LOG(SSH_LOG_DEBUG, "Option not allowed in Match block: %s, line: %d", + keyword, count); + break; + case BIND_CFG_UNKNOWN: +diff --git a/src/channels.c b/src/channels.c +index 73a6ffe4..440707d6 100644 +--- a/src/channels.c ++++ b/src/channels.c +@@ -192,7 +192,7 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){ + if (rc != SSH_OK) + goto error; + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d", + channel->local_channel, + channel->remote_channel); +@@ -205,7 +205,7 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){ + goto error; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Remote window : %"PRIu32", maxpacket : %"PRIu32, + (uint32_t) channel->remote_window, + (uint32_t) channel->remote_maxpacket); +@@ -327,7 +327,7 @@ channel_open(ssh_channel channel, + channel->local_maxpacket = maxpacket; + channel->local_window = window; + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Creating a channel %d with %d window and %d max packet", + channel->local_channel, window, maxpacket); + +@@ -417,7 +417,7 @@ static int grow_window(ssh_session session, + int rc; + + if (new_window <= channel->local_window) { +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "growing window (channel %d:%d) to %d bytes : not needed (%d bytes)", + channel->local_channel, channel->remote_channel, new_window, + channel->local_window); +@@ -441,7 +441,7 @@ static int grow_window(ssh_session session, + goto error; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "growing window (channel %d:%d) to %d bytes", + channel->local_channel, + channel->remote_channel, +@@ -512,7 +512,7 @@ SSH_PACKET_CALLBACK(channel_rcv_change_window) { + return SSH_PACKET_USED; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Adding %d bytes to channel (%d:%d) (from %d bytes)", + bytes, + channel->local_channel, +@@ -831,7 +831,7 @@ SSH_PACKET_CALLBACK(channel_rcv_request) { + } + if(strcmp(request,"keepalive@openssh.com")==0){ + SAFE_FREE(request); +- SSH_LOG(SSH_LOG_PROTOCOL,"Responding to Openssh's keepalive"); ++ SSH_LOG(SSH_LOG_DEBUG,"Responding to Openssh's keepalive"); + + rc = ssh_buffer_pack(session->out_buffer, + "bd", +@@ -849,7 +849,7 @@ SSH_PACKET_CALLBACK(channel_rcv_request) { + int status; + + SAFE_FREE(request); +- SSH_LOG(SSH_LOG_PROTOCOL, "Received an auth-agent-req request"); ++ SSH_LOG(SSH_LOG_DEBUG, "Received an auth-agent-req request"); + + status = SSH2_MSG_CHANNEL_FAILURE; + ssh_callbacks_iterate(channel->callbacks, +@@ -884,7 +884,7 @@ SSH_PACKET_CALLBACK(channel_rcv_request) { + */ + ssh_message_handle_channel_request(session,channel,packet,request,want_reply); + #else +- SSH_LOG(SSH_LOG_WARNING, "Unhandled channel request %s", request); ++ SSH_LOG(SSH_LOG_DEBUG, "Unhandled channel request %s", request); + #endif + + SAFE_FREE(request); +@@ -1490,14 +1490,14 @@ static int channel_write_common(ssh_channel channel, + } + while (len > 0) { + if (channel->remote_window < len) { +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Remote window is %d bytes. going to write %d bytes", + channel->remote_window, + len); + /* What happens when the channel window is zero? */ + if(channel->remote_window == 0) { + /* nothing can be written */ +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Wait for a growing window message..."); + rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_DEFAULT, + ssh_channel_waitwindow_termination,channel); +@@ -1822,7 +1822,7 @@ pending: + rc=SSH_ERROR; + break; + case SSH_CHANNEL_REQ_STATE_ACCEPTED: +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Channel request %s success",request); + rc=SSH_OK; + break; +@@ -2396,7 +2396,7 @@ pending: + } + switch(session->global_req_state){ + case SSH_CHANNEL_REQ_STATE_ACCEPTED: +- SSH_LOG(SSH_LOG_PROTOCOL, "Global request %s success",request); ++ SSH_LOG(SSH_LOG_DEBUG, "Global request %s success",request); + rc=SSH_OK; + break; + case SSH_CHANNEL_REQ_STATE_DENIED: +diff --git a/src/client.c b/src/client.c +index 7a967048..da03f22b 100644 +--- a/src/client.c ++++ b/src/client.c +@@ -406,7 +406,7 @@ static void ssh_client_connection_callback(ssh_session session) + goto error; + } + set_status(session, 0.4f); +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "SSH server banner: %s", session->serverbanner); + + /* Here we analyze the different protocols the server allows. */ +@@ -566,7 +566,7 @@ int ssh_connect(ssh_session session) + return SSH_ERROR; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "libssh %s, using threading %s", + ssh_copyright(), + ssh_threads_get_type()); +@@ -601,7 +601,7 @@ int ssh_connect(ssh_session session) + set_status(session, 0.2f); + + session->alive = 1; +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Socket connecting, now waiting for the callbacks to work"); + + pending: +diff --git a/src/config.c b/src/config.c +index ae2a0c4c..8ed08d44 100644 +--- a/src/config.c ++++ b/src/config.c +@@ -667,7 +667,7 @@ ssh_config_parse_line(ssh_session session, + break; + } + args++; +- SSH_LOG(SSH_LOG_TRACE, "line %d: Processing Match keyword '%s'", ++ SSH_LOG(SSH_LOG_DEBUG, "line %d: Processing Match keyword '%s'", + count, p); + + /* If the option is prefixed with ! the result should be negated */ +@@ -699,7 +699,7 @@ ssh_config_parse_line(ssh_session session, + + case MATCH_FINAL: + case MATCH_CANONICAL: +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_DEBUG, + "line %d: Unsupported Match keyword '%s', skipping", + count, + p); +@@ -717,7 +717,7 @@ ssh_config_parse_line(ssh_session session, + return -1; + } + if (result != 1) { +- SSH_LOG(SSH_LOG_INFO, "line %d: Skipped match exec " ++ SSH_LOG(SSH_LOG_DEBUG, "line %d: Skipped match exec " + "'%s' as previous conditions already failed.", + count, p2); + continue; +diff --git a/src/curve25519.c b/src/curve25519.c +index 6a930faf..89206903 100644 +--- a/src/curve25519.c ++++ b/src/curve25519.c +@@ -339,7 +339,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){ + goto error; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent"); + session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; + + return SSH_PACKET_USED; +@@ -491,7 +491,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){ + goto error; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_ECDH_REPLY sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_KEX_ECDH_REPLY sent"); + rc = ssh_packet_send(session); + if (rc == SSH_ERROR) { + return SSH_ERROR; +@@ -508,7 +508,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){ + if (rc == SSH_ERROR) { + goto error; + } +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent"); + + return SSH_PACKET_USED; + error: +diff --git a/src/dh-gex.c b/src/dh-gex.c +index d0d2890b..6f9cd3f1 100644 +--- a/src/dh-gex.c ++++ b/src/dh-gex.c +@@ -116,7 +116,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group) + (void) type; + (void) user; + +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_DH_GEX_GROUP received"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_KEX_DH_GEX_GROUP received"); + + if (bignum_ctx_invalid(ctx)) { + goto error; +@@ -256,7 +256,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply) + bignum server_pubkey = NULL; + (void)type; + (void)user; +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_DH_GEX_REPLY received"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_KEX_DH_GEX_REPLY received"); + + ssh_packet_remove_callbacks(session, &ssh_dhgex_client_callbacks); + rc = ssh_buffer_unpack(packet, +@@ -300,7 +300,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply) + if (rc == SSH_ERROR) { + goto error; + } +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent"); + session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; + + return SSH_PACKET_USED; +@@ -435,7 +435,7 @@ static int ssh_retrieve_dhgroup_file(FILE *moduli, + if (rc == EOF) { + break; + } +- SSH_LOG(SSH_LOG_INFO, "Invalid moduli entry line %zu", line); ++ SSH_LOG(SSH_LOG_DEBUG, "Invalid moduli entry line %zu", line); + do { + firstbyte = getc(moduli); + } while(firstbyte != '\n' && firstbyte != EOF); +@@ -473,13 +473,13 @@ static int ssh_retrieve_dhgroup_file(FILE *moduli, + } + } + if (*best_size != 0) { +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_DEBUG, + "Selected %zu bits modulus out of %zu candidates in %zu lines", + *best_size, + best_nlines - 1, + line); + } else { +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_DEBUG, + "No moduli found for [%u:%u:%u]", + pmin, + pn, +@@ -526,7 +526,7 @@ static int ssh_retrieve_dhgroup(char *moduli_file, + + if (moduli == NULL) { + char err_msg[SSH_ERRNO_MSG_MAX] = {0}; +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_DEBUG, + "Unable to open moduli file: %s", + ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX)); + return ssh_fallback_group(pmax, p, g); +@@ -621,7 +621,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request) + ssh_set_error_invalid(session); + goto error; + } +- SSH_LOG(SSH_LOG_INFO, "dh-gex: DHGEX_REQUEST[%u:%u:%u]", pmin, pn, pmax); ++ SSH_LOG(SSH_LOG_DEBUG, "dh-gex: DHGEX_REQUEST[%u:%u:%u]", pmin, pn, pmax); + + if (pmin > pn || pn > pmax || pn > DH_PMAX || pmax < DH_PMIN) { + ssh_set_error(session, +diff --git a/src/dh.c b/src/dh.c +index 1251eb64..cf63fec9 100644 +--- a/src/dh.c ++++ b/src/dh.c +@@ -400,7 +400,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply){ + goto error; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent"); + session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; + return SSH_PACKET_USED; + error: +diff --git a/src/ecdh.c b/src/ecdh.c +index a4c07ccb..b57789d4 100644 +--- a/src/ecdh.c ++++ b/src/ecdh.c +@@ -97,7 +97,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply){ + goto error; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent"); + session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; + + return SSH_PACKET_USED; +diff --git a/src/ecdh_crypto.c b/src/ecdh_crypto.c +index 51084b7a..e3ed8eb1 100644 +--- a/src/ecdh_crypto.c ++++ b/src/ecdh_crypto.c +@@ -613,7 +613,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ + goto error; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_KEXDH_REPLY sent"); + rc = ssh_packet_send(session); + if (rc == SSH_ERROR) { + goto error; +@@ -630,7 +630,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ + if (rc == SSH_ERROR){ + goto error; + } +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent"); + + return SSH_PACKET_USED; + error: +diff --git a/src/ecdh_gcrypt.c b/src/ecdh_gcrypt.c +index d9c41bf9..ca643467 100644 +--- a/src/ecdh_gcrypt.c ++++ b/src/ecdh_gcrypt.c +@@ -366,7 +366,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ + goto out; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_KEXDH_REPLY sent"); + rc = ssh_packet_send(session); + if (rc != SSH_OK) { + goto out; +@@ -381,7 +381,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ + + session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; + rc = ssh_packet_send(session); +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent"); + + out: + gcry_sexp_release(param); +diff --git a/src/ecdh_mbedcrypto.c b/src/ecdh_mbedcrypto.c +index cfe017a0..1c930fb5 100644 +--- a/src/ecdh_mbedcrypto.c ++++ b/src/ecdh_mbedcrypto.c +@@ -311,7 +311,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ + goto out; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_KEXDH_REPLY sent"); + rc = ssh_packet_send(session); + if (rc != SSH_OK) { + rc = SSH_ERROR; +@@ -326,7 +326,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ + + session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; + rc = ssh_packet_send(session); +- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent"); + + out: + mbedtls_ecp_group_free(&grp); +diff --git a/src/gssapi.c b/src/gssapi.c +index f60f8d72..3fcbc1fe 100644 +--- a/src/gssapi.c ++++ b/src/gssapi.c +@@ -224,8 +224,8 @@ ssh_gssapi_handle_userauth(ssh_session session, const char *user, + + maj_stat = gss_indicate_mechs(&min_stat, &supported); + if (maj_stat != GSS_S_COMPLETE) { +- SSH_LOG(SSH_LOG_WARNING, "indicate mecks %d, %d", maj_stat, min_stat); +- ssh_gssapi_log_error(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_DEBUG, "indicate mecks %d, %d", maj_stat, min_stat); ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "indicate mechs", + maj_stat, + min_stat); +@@ -259,7 +259,7 @@ ssh_gssapi_handle_userauth(ssh_session session, const char *user, + } + gss_release_oid_set(&min_stat, &supported); + if (oid_count == 0){ +- SSH_LOG(SSH_LOG_PROTOCOL,"GSSAPI: no OID match"); ++ SSH_LOG(SSH_LOG_DEBUG,"GSSAPI: no OID match"); + ssh_auth_reply_default(session, 0); + gss_release_oid_set(&min_stat, &both_supported); + return SSH_OK; +@@ -273,8 +273,8 @@ ssh_gssapi_handle_userauth(ssh_session session, const char *user, + maj_stat = gss_import_name(&min_stat, &name_buf, + (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name); + if (maj_stat != GSS_S_COMPLETE) { +- SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat); +- ssh_gssapi_log_error(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_DEBUG, "importing name %d, %d", maj_stat, min_stat); ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "importing name", + maj_stat, + min_stat); +@@ -297,7 +297,7 @@ ssh_gssapi_handle_userauth(ssh_session session, const char *user, + return SSH_ERROR; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "acquiring credentials %d, %d", maj_stat, min_stat); ++ SSH_LOG(SSH_LOG_DEBUG, "acquiring credentials %d, %d", maj_stat, min_stat); + + /* finding which OID from client we selected */ + for (i=0 ; i< n_oid ; ++i){ +@@ -339,7 +339,7 @@ static char *ssh_gssapi_name_to_char(gss_name_t name) + OM_uint32 maj_stat, min_stat; + char *ptr; + maj_stat = gss_display_name(&min_stat, name, &buffer, NULL); +- ssh_gssapi_log_error(SSH_LOG_WARNING, ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "converting name", + maj_stat, + min_stat); +@@ -414,7 +414,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){ + maj_stat = gss_accept_sec_context(&min_stat, &session->gssapi->ctx, session->gssapi->server_creds, + &input_token, input_bindings, &client_name, NULL /*mech_oid*/, &output_token, &ret_flags, + NULL /*time*/, &session->gssapi->client_creds); +- ssh_gssapi_log_error(SSH_LOG_PROTOCOL, ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "accepting token", + maj_stat, + min_stat); +@@ -424,7 +424,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){ + session->gssapi->canonic_user = ssh_gssapi_name_to_char(client_name); + } + if (GSS_ERROR(maj_stat)){ +- ssh_gssapi_log_error(SSH_LOG_WARNING, ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "Gssapi error", + maj_stat, + min_stat); +@@ -531,7 +531,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic) + mic_token_buf.value = ssh_string_data(mic_token); + + maj_stat = gss_verify_mic(&min_stat, session->gssapi->ctx, &mic_buf, &mic_token_buf, NULL); +- ssh_gssapi_log_error(SSH_LOG_PROTOCOL, ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "verifying MIC", + maj_stat, + min_stat); +@@ -750,8 +750,8 @@ int ssh_gssapi_auth_mic(ssh_session session) + (gss_OID)GSS_C_NT_HOSTBASED_SERVICE, + &session->gssapi->client.server_name); + if (maj_stat != GSS_S_COMPLETE) { +- SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat); +- ssh_gssapi_log_error(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_DEBUG, "importing name %d, %d", maj_stat, min_stat); ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "importing name", + maj_stat, + min_stat); +@@ -765,7 +765,7 @@ int ssh_gssapi_auth_mic(ssh_session session) + return SSH_AUTH_ERROR; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "Authenticating with gssapi to host %s with user %s", ++ SSH_LOG(SSH_LOG_DEBUG, "Authenticating with gssapi to host %s with user %s", + session->opts.host, session->gssapi->user); + rc = ssh_gssapi_match(session, &selected); + if (rc == SSH_ERROR) { +@@ -773,7 +773,7 @@ int ssh_gssapi_auth_mic(ssh_session session) + } + + n_oids = selected->count; +- SSH_LOG(SSH_LOG_PROTOCOL, "Sending %zu oids", n_oids); ++ SSH_LOG(SSH_LOG_DEBUG, "Sending %zu oids", n_oids); + + oids = calloc(n_oids, sizeof(ssh_string)); + if (oids == NULL) { +@@ -886,7 +886,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){ + 0, NULL, &input_token, NULL, + &output_token, NULL, NULL); + if(GSS_ERROR(maj_stat)){ +- ssh_gssapi_log_error(SSH_LOG_WARNING, ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "Initializing gssapi context", + maj_stat, + min_stat); +@@ -935,7 +935,7 @@ static int ssh_gssapi_send_mic(ssh_session session) + &mic_buf, &mic_token_buf); + if (GSS_ERROR(maj_stat)){ + SSH_BUFFER_FREE(mic_buffer); +- ssh_gssapi_log_error(SSH_LOG_PROTOCOL, ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "generating MIC", + maj_stat, + min_stat); +@@ -992,13 +992,13 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){ + 0, NULL, &input_token, NULL, + &output_token, NULL, NULL); + +- ssh_gssapi_log_error(SSH_LOG_PROTOCOL, ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "accepting token", + maj_stat, + min_stat); + SSH_STRING_FREE(token); + if (GSS_ERROR(maj_stat)){ +- ssh_gssapi_log_error(SSH_LOG_PROTOCOL, ++ ssh_gssapi_log_error(SSH_LOG_DEBUG, + "Gssapi error", + maj_stat, + min_stat); +diff --git a/src/kex.c b/src/kex.c +index 52d9c2ee..64083997 100644 +--- a/src/kex.c ++++ b/src/kex.c +@@ -356,7 +356,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit) + (void)user; + + if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED) { +- SSH_LOG(SSH_LOG_INFO, "Initiating key re-exchange"); ++ SSH_LOG(SSH_LOG_DEBUG, "Initiating key re-exchange"); + } else if (session->session_state != SSH_SESSION_STATE_INITIAL_KEX) { + ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state"); + goto error; +@@ -824,7 +824,7 @@ int ssh_kex_select_methods (ssh_session session) + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256") == 0){ + session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256; + } +- SSH_LOG(SSH_LOG_INFO, "Negotiated %s,%s,%s,%s,%s,%s,%s,%s,%s,%s", ++ SSH_LOG(SSH_LOG_DEBUG, "Negotiated %s,%s,%s,%s,%s,%s,%s,%s,%s,%s", + session->next_crypto->kex_methods[SSH_KEX], + session->next_crypto->kex_methods[SSH_HOSTKEYS], + session->next_crypto->kex_methods[SSH_CRYPT_C_S], +diff --git a/src/libcrypto.c b/src/libcrypto.c +index d2fe2289..7fb3ba4d 100644 +--- a/src/libcrypto.c ++++ b/src/libcrypto.c +@@ -109,7 +109,7 @@ ENGINE *pki_get_engine(void) + ERR_error_string(ERR_get_error(), NULL)); + return NULL; + } +- SSH_LOG(SSH_LOG_INFO, "Engine loaded successfully"); ++ SSH_LOG(SSH_LOG_DEBUG, "Engine loaded successfully"); + + ok = ENGINE_init(engine); + if (!ok) { +@@ -120,7 +120,7 @@ ENGINE *pki_get_engine(void) + return NULL; + } + +- SSH_LOG(SSH_LOG_INFO, "Engine init success"); ++ SSH_LOG(SSH_LOG_DEBUG, "Engine init success"); + } + return engine; + } +@@ -532,7 +532,7 @@ static void evp_cipher_encrypt(struct ssh_cipher_struct *cipher, + return; + } + if (outlen != (int)len){ +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_DEBUG, + "EVP_EncryptUpdate: output size %d for %zu in", + outlen, + len); +@@ -558,7 +558,7 @@ static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher, + return; + } + if (outlen != (int)len){ +- SSH_LOG(SSH_LOG_WARNING, ++ SSH_LOG(SSH_LOG_DEBUG, + "EVP_DecryptUpdate: output size %d for %zu in", + outlen, + len); +@@ -1377,7 +1377,7 @@ int ssh_crypto_init(void) + return SSH_OK; + } + if (OpenSSL_version_num() != OPENSSL_VERSION_NUMBER){ +- SSH_LOG(SSH_LOG_WARNING, "libssh compiled with %s " ++ SSH_LOG(SSH_LOG_DEBUG, "libssh compiled with %s " + "headers, currently running with %s.", + OPENSSL_VERSION_TEXT, + OpenSSL_version(OpenSSL_version_num()) +diff --git a/src/libgcrypt.c b/src/libgcrypt.c +index a450e78a..0b6ccc39 100644 +--- a/src/libgcrypt.c ++++ b/src/libgcrypt.c +@@ -433,7 +433,7 @@ aes_gcm_decrypt(struct ssh_cipher_struct *cipher, + (unsigned char *)complete_packet + aadlen + encrypted_size, + authlen); + if (gpg_err_code(err) == GPG_ERR_CHECKSUM) { +- SSH_LOG(SSH_LOG_WARNING, "The authentication tag does not match"); ++ SSH_LOG(SSH_LOG_DEBUG, "The authentication tag does not match"); + return SSH_ERROR; + } else if (err != GPG_ERR_NO_ERROR) { + SSH_LOG(SSH_LOG_TRACE, "General error while decryption: %s", +diff --git a/src/libmbedcrypto.c b/src/libmbedcrypto.c +index e3baecca..4f4d21c3 100644 +--- a/src/libmbedcrypto.c ++++ b/src/libmbedcrypto.c +@@ -429,7 +429,7 @@ static void cipher_encrypt(struct ssh_cipher_struct *cipher, + } + + if (total_len != len) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update: output size %zu for %zu", ++ SSH_LOG(SSH_LOG_DEBUG, "mbedtls_cipher_update: output size %zu for %zu", + outlen, len); + return; + } +@@ -448,7 +448,7 @@ static void cipher_encrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void + } + + if (outlen != len) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update: output size %zu for %zu", ++ SSH_LOG(SSH_LOG_DEBUG, "mbedtls_cipher_update: output size %zu for %zu", + outlen, len); + return; + } +@@ -487,7 +487,7 @@ static void cipher_decrypt(struct ssh_cipher_struct *cipher, + total_len += outlen; + + if (total_len != len) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update: output size %zu for %zu", ++ SSH_LOG(SSH_LOG_DEBUG, "mbedtls_cipher_update: output size %zu for %zu", + outlen, len); + return; + } +@@ -532,7 +532,7 @@ static void cipher_decrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void + } + + if (outlen != len) { +- SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update: output size %zu for %zu", ++ SSH_LOG(SSH_LOG_DEBUG, "mbedtls_cipher_update: output size %zu for %zu", + outlen, len); + return; + } +diff --git a/src/messages.c b/src/messages.c +index 8d05e248..91d23e7d 100644 +--- a/src/messages.c ++++ b/src/messages.c +@@ -1055,7 +1055,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){ + } + + if (session->kbdint == NULL) { +- SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Got a keyboard-interactive " ++ SSH_LOG(SSH_LOG_DEBUG, "Warning: Got a keyboard-interactive " + "response but it seems we didn't send the request."); + + session->kbdint = ssh_kbdint_new(); +@@ -1089,7 +1089,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){ + + if(nanswers != session->kbdint->nprompts) { + /* warn but let the application handle this case */ +- SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Number of prompts and answers" ++ SSH_LOG(SSH_LOG_DEBUG, "Warning: Number of prompts and answers" + " mismatch: p=%u a=%u", session->kbdint->nprompts, nanswers); + } + session->kbdint->nanswers = nanswers; +@@ -1496,7 +1496,7 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){ + (void)type; + (void)packet; + +- SSH_LOG(SSH_LOG_PROTOCOL,"Received SSH_MSG_GLOBAL_REQUEST packet"); ++ SSH_LOG(SSH_LOG_DEBUG,"Received SSH_MSG_GLOBAL_REQUEST packet"); + r = ssh_buffer_unpack(packet, "sb", + &request, + &want_reply); +@@ -1528,12 +1528,12 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){ + msg->global_request.type = SSH_GLOBAL_REQUEST_TCPIP_FORWARD; + msg->global_request.want_reply = want_reply; + +- SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, ++ SSH_LOG(SSH_LOG_DEBUG, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, + msg->global_request.bind_address, + msg->global_request.bind_port); + + if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) { +- SSH_LOG(SSH_LOG_PROTOCOL, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, ++ SSH_LOG(SSH_LOG_DEBUG, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, + want_reply, msg->global_request.bind_address, + msg->global_request.bind_port); + session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata); +@@ -1558,7 +1558,7 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){ + msg->global_request.type = SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD; + msg->global_request.want_reply = want_reply; + +- SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, ++ SSH_LOG(SSH_LOG_DEBUG, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, + msg->global_request.bind_address, + msg->global_request.bind_port); + +@@ -1572,14 +1572,14 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){ + } else if(strcmp(request, "keepalive@openssh.com") == 0) { + msg->global_request.type = SSH_GLOBAL_REQUEST_KEEPALIVE; + msg->global_request.want_reply = want_reply; +- SSH_LOG(SSH_LOG_PROTOCOL, "Received keepalive@openssh.com %d", want_reply); ++ SSH_LOG(SSH_LOG_DEBUG, "Received keepalive@openssh.com %d", want_reply); + if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) { + session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata); + } else { + ssh_message_global_request_reply_success(msg, 0); + } + } else { +- SSH_LOG(SSH_LOG_PROTOCOL, "UNKNOWN SSH_MSG_GLOBAL_REQUEST %s, " ++ SSH_LOG(SSH_LOG_DEBUG, "UNKNOWN SSH_MSG_GLOBAL_REQUEST %s, " + "want_reply = %d", request, want_reply); + goto reply_with_failure; + } +diff --git a/src/misc.c b/src/misc.c +index a70ccd04..87977a3f 100644 +--- a/src/misc.c ++++ b/src/misc.c +@@ -634,7 +634,7 @@ void ssh_log_hexdump(const char *descr, const unsigned char *what, size_t len) + return; + + error: +- SSH_LOG(SSH_LOG_WARN, "Could not print to buffer"); ++ SSH_LOG(SSH_LOG_DEBUG, "Could not print to buffer"); + return; + } + +@@ -1330,7 +1330,7 @@ int ssh_analyze_banner(ssh_session session, int server) + return -1; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "Analyzing banner: %s", banner); ++ SSH_LOG(SSH_LOG_DEBUG, "Analyzing banner: %s", banner); + + switch (banner[4]) { + case '2': +@@ -1384,7 +1384,7 @@ int ssh_analyze_banner(ssh_session session, int server) + + session->openssh = SSH_VERSION_INT(((int) major), ((int) minor), 0); + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "We are talking to an OpenSSH %s version: %lu.%lu (%x)", + server ? "client" : "server", + major, minor, session->openssh); +@@ -1488,7 +1488,7 @@ int ssh_timeout_elapsed(struct ssh_timestamp *ts, int timeout) + * -2 means user-defined timeout as available in + * session->timeout, session->timeout_usec. + */ +- SSH_LOG(SSH_LOG_WARN, "ssh_timeout_elapsed called with -2. this needs to " ++ SSH_LOG(SSH_LOG_DEBUG, "ssh_timeout_elapsed called with -2. this needs to " + "be fixed. please set a breakpoint on misc.c:%d and " + "fix the caller\n", __LINE__); + return 0; +diff --git a/src/packet.c b/src/packet.c +index ab0e1a4c..f9d37dea 100644 +--- a/src/packet.c ++++ b/src/packet.c +@@ -1867,7 +1867,7 @@ ssh_init_rekey_state(struct ssh_session_struct *session, + session->opts.rekey_data / cipher->blocksize); + } + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Set rekey after %" PRIu64 " blocks", + cipher->max_blocks); + } +@@ -1969,7 +1969,7 @@ ssh_packet_set_newkeys(ssh_session session, + ssh_init_rekey_state(session, in_cipher); + if (session->opts.rekey_time != 0) { + ssh_timestamp_init(&session->last_rekey_time); +- SSH_LOG(SSH_LOG_PROTOCOL, "Set rekey after %" PRIu32 " seconds", ++ SSH_LOG(SSH_LOG_DEBUG, "Set rekey after %" PRIu32 " seconds", + session->opts.rekey_time/1000); + } + +diff --git a/src/packet_cb.c b/src/packet_cb.c +index 39575b17..98d21b12 100644 +--- a/src/packet_cb.c ++++ b/src/packet_cb.c +@@ -87,7 +87,7 @@ SSH_PACKET_CALLBACK(ssh_packet_ignore_callback){ + (void)user; + (void)type; + (void)packet; +- SSH_LOG(SSH_LOG_PROTOCOL,"Received %s packet",type==SSH2_MSG_IGNORE ? "SSH_MSG_IGNORE" : "SSH_MSG_DEBUG"); ++ SSH_LOG(SSH_LOG_DEBUG,"Received %s packet",type==SSH2_MSG_IGNORE ? "SSH_MSG_IGNORE" : "SSH_MSG_DEBUG"); + /* TODO: handle a graceful disconnect */ + return SSH_PACKET_USED; + } +@@ -99,7 +99,7 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){ + (void)packet; + (void)user; + (void)type; +- SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_NEWKEYS"); ++ SSH_LOG(SSH_LOG_DEBUG, "Received SSH_MSG_NEWKEYS"); + + if (session->session_state != SSH_SESSION_STATE_DH || + session->dh_handshake_state != DH_STATE_NEWKEYS_SENT) { +@@ -158,7 +158,7 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){ + if (rc == SSH_ERROR) { + goto error; + } +- SSH_LOG(SSH_LOG_PROTOCOL,"Signature verified and valid"); ++ SSH_LOG(SSH_LOG_DEBUG,"Signature verified and valid"); + + /* When receiving this packet, we switch on the incomming crypto. */ + rc = ssh_packet_set_newkeys(session, SSH_DIRECTION_IN); +diff --git a/src/pki.c b/src/pki.c +index b109cc96..512201d9 100644 +--- a/src/pki.c ++++ b/src/pki.c +@@ -690,7 +690,7 @@ int ssh_key_cmp(const ssh_key k1, + } + + if (k1->type != k2->type) { +- SSH_LOG(SSH_LOG_WARN, "key types don't match!"); ++ SSH_LOG(SSH_LOG_DEBUG, "key types don't match!"); + return 1; + } + +@@ -823,7 +823,7 @@ int ssh_pki_import_privkey_base64(const char *b64_key, + return SSH_ERROR; + } + +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_DEBUG, + "Trying to decode privkey passphrase=%s", + passphrase ? "true" : "false"); + +diff --git a/src/pki_container_openssh.c b/src/pki_container_openssh.c +index d78800fd..fc51c43c 100644 +--- a/src/pki_container_openssh.c ++++ b/src/pki_container_openssh.c +@@ -298,7 +298,7 @@ ssh_pki_openssh_import(const char *text_key, + SSH_LOG(SSH_LOG_TRACE, "Not an OpenSSH private key (bad magic)"); + goto out; + } +- SSH_LOG(SSH_LOG_INFO, ++ SSH_LOG(SSH_LOG_DEBUG, + "Opening OpenSSH private key: ciphername: %s, kdf: %s, nkeys: %d", + ciphername, + kdfname, +@@ -478,7 +478,7 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer, + return SSH_ERROR; + } + +- SSH_LOG(SSH_LOG_WARN, "Encryption: %d key, %d IV, %d rounds, %zu bytes salt", ++ SSH_LOG(SSH_LOG_DEBUG, "Encryption: %d key, %d IV, %d rounds, %zu bytes salt", + cipher.keysize/8, + cipher.blocksize, rounds, ssh_string_len(salt)); + +@@ -559,7 +559,7 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey, + return NULL; + } + if (passphrase != NULL || auth_fn != NULL){ +- SSH_LOG(SSH_LOG_INFO, "Enabling encryption for private key export"); ++ SSH_LOG(SSH_LOG_DEBUG, "Enabling encryption for private key export"); + to_encrypt = 1; + } + buffer = ssh_buffer_new(); +diff --git a/src/scp.c b/src/scp.c +index ef5aa139..04eb4f1b 100644 +--- a/src/scp.c ++++ b/src/scp.c +@@ -146,7 +146,7 @@ int ssh_scp_init(ssh_scp scp) + return SSH_ERROR; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "Initializing scp session %s %son location '%s'", ++ SSH_LOG(SSH_LOG_DEBUG, "Initializing scp session %s %son location '%s'", + scp->mode == SSH_SCP_WRITE?"write":"read", + scp->recursive ? "recursive " : "", + scp->location); +@@ -376,7 +376,7 @@ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode) + goto error; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "SCP pushing directory %s with permissions '%s'", + vis_encoded, perms); + +@@ -517,7 +517,7 @@ int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, + goto error; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "SCP pushing file %s, size %" PRIu64 " with permissions '%s'", + vis_encoded, size, perms); + +@@ -825,7 +825,7 @@ int ssh_scp_pull_request(ssh_scp scp) + *p = '\0'; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "Received SCP request: '%s'", buffer); ++ SSH_LOG(SSH_LOG_DEBUG, "Received SCP request: '%s'", buffer); + switch(buffer[0]) { + case 'C': + /* File */ +diff --git a/src/server.c b/src/server.c +index 04949a94..3fc25bd9 100644 +--- a/src/server.c ++++ b/src/server.c +@@ -348,7 +348,7 @@ static void ssh_server_connection_callback(ssh_session session){ + goto error; + } + set_status(session, 0.4f); +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "SSH client banner: %s", session->clientbanner); + + /* Here we analyze the different protocols the server allows. */ +@@ -907,9 +907,8 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name, + + /* fill in the kbdint structure */ + if (msg->session->kbdint == NULL) { +- SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Got a " +- "keyboard-interactive response but it " +- "seems we didn't send the request."); ++ SSH_LOG(SSH_LOG_DEBUG, "Warning: Got a keyboard-interactive response " ++ "but it seems we didn't send the request."); + + msg->session->kbdint = ssh_kbdint_new(); + if (msg->session->kbdint == NULL) { +@@ -1004,13 +1003,13 @@ int ssh_auth_reply_success(ssh_session session, int partial) + + crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT); + if (crypto != NULL && crypto->delayed_compress_out) { +- SSH_LOG(SSH_LOG_PROTOCOL, "Enabling delayed compression OUT"); ++ SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression OUT"); + crypto->do_compress_out = 1; + } + + crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN); + if (crypto != NULL && crypto->delayed_compress_in) { +- SSH_LOG(SSH_LOG_PROTOCOL, "Enabling delayed compression IN"); ++ SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression IN"); + crypto->do_compress_in = 1; + } + return r; +diff --git a/src/sftp.c b/src/sftp.c +index e01012a8..9906e5aa 100644 +--- a/src/sftp.c ++++ b/src/sftp.c +@@ -317,7 +317,7 @@ int sftp_server_init(sftp_session sftp){ + } + SSH_BUFFER_FREE(reply); + +- SSH_LOG(SSH_LOG_PROTOCOL, "Server version sent"); ++ SSH_LOG(SSH_LOG_DEBUG, "Server version sent"); + + if (version > LIBSFTP_VERSION) { + sftp->version = LIBSFTP_VERSION; +@@ -701,7 +701,7 @@ int sftp_init(sftp_session sftp) { + sftp_set_error(sftp, SSH_FX_FAILURE); + return -1; + } +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "SFTP server version %d", + version); + rc = ssh_buffer_unpack(packet->payload, "s", &ext_name); +@@ -714,7 +714,7 @@ int sftp_init(sftp_session sftp) { + break; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "SFTP server extension: %s, version: %s", + ext_name, ext_data); + +@@ -1347,7 +1347,7 @@ static sftp_attributes sftp_parse_attr_3(sftp_session sftp, ssh_buffer buf, + if (rc != SSH_OK){ + goto error; + } +- SSH_LOG(SSH_LOG_PROTOCOL, "Name: %s", attr->name); ++ SSH_LOG(SSH_LOG_DEBUG, "Name: %s", attr->name); + + /* Set owner and group if we talk to openssh and have the longname */ + if (ssh_get_openssh_version(sftp->session)) { +@@ -1367,7 +1367,7 @@ static sftp_attributes sftp_parse_attr_3(sftp_session sftp, ssh_buffer buf, + if (rc != SSH_OK){ + goto error; + } +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Flags: %.8"PRIx32"\n", (uint32_t) attr->flags); + + if (attr->flags & SSH_FILEXFER_ATTR_SIZE) { +@@ -1375,7 +1375,7 @@ static sftp_attributes sftp_parse_attr_3(sftp_session sftp, ssh_buffer buf, + if(rc != SSH_OK) { + goto error; + } +- SSH_LOG(SSH_LOG_PROTOCOL, ++ SSH_LOG(SSH_LOG_DEBUG, + "Size: %"PRIu64"\n", + (uint64_t) attr->size); + } +@@ -1638,7 +1638,7 @@ sftp_attributes sftp_readdir(sftp_session sftp, sftp_dir dir) + return NULL; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "Count is %d", dir->count); ++ SSH_LOG(SSH_LOG_DEBUG, "Count is %d", dir->count); + + attr = sftp_parse_attr(sftp, dir->buffer, 1); + if (attr == NULL) { +diff --git a/src/socket.c b/src/socket.c +index 16c84e0e..35838e86 100644 +--- a/src/socket.c ++++ b/src/socket.c +@@ -868,7 +868,7 @@ int ssh_socket_connect(ssh_socket s, + return SSH_ERROR; + } + fd = ssh_connect_host_nonblocking(s->session, host, bind_addr, port); +- SSH_LOG(SSH_LOG_PROTOCOL, "Nonblocking connection socket: %d", fd); ++ SSH_LOG(SSH_LOG_DEBUG, "Nonblocking connection socket: %d", fd); + if (fd == SSH_INVALID_SOCKET) { + return SSH_ERROR; + } +@@ -955,7 +955,7 @@ ssh_socket_connect_proxycommand(ssh_socket s, const char *command) + return SSH_ERROR; + } + +- SSH_LOG(SSH_LOG_PROTOCOL, "Executing proxycommand '%s'", command); ++ SSH_LOG(SSH_LOG_DEBUG, "Executing proxycommand '%s'", command); + pid = fork(); + if (pid == 0) { + ssh_execute_command(command, pair[0], pair[0]); +@@ -963,7 +963,7 @@ ssh_socket_connect_proxycommand(ssh_socket s, const char *command) + } + s->proxy_pid = pid; + close(pair[0]); +- SSH_LOG(SSH_LOG_PROTOCOL, "ProxyCommand connection pipe: [%d,%d]",pair[0],pair[1]); ++ SSH_LOG(SSH_LOG_DEBUG, "ProxyCommand connection pipe: [%d,%d]",pair[0],pair[1]); + ssh_socket_set_fd(s, pair[1]); + s->state=SSH_SOCKET_CONNECTED; + s->fd_is_socket=0; +-- +2.38.1 + + +From 28019965e79eeafb0de7502baa1bcccfcd3b00df Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Thu, 15 Sep 2022 21:14:50 +0200 +Subject: [PATCH 4/5] SSH_LOG_WARN: Recategorize loglevels + +These warning should be logging when something fatal happens and give +information on the error to the user. + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +Reviewed-by: Andreas Schneider +--- + src/auth.c | 4 ++-- + src/client.c | 2 +- + src/config.c | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/auth.c b/src/auth.c +index 17376c8f..08d895a2 100644 +--- a/src/auth.c ++++ b/src/auth.c +@@ -1288,8 +1288,8 @@ int ssh_userauth_publickey_auto(ssh_session session, + /* continue */ + } + } +- SSH_LOG(SSH_LOG_INFO, +- "Tried every public key, none matched"); ++ SSH_LOG(SSH_LOG_WARN, ++ "Access denied: Tried every public key, none matched"); + SAFE_FREE(session->auth.auto_state); + return SSH_AUTH_DENIED; + } +diff --git a/src/client.c b/src/client.c +index da03f22b..022bbd84 100644 +--- a/src/client.c ++++ b/src/client.c +@@ -481,7 +481,7 @@ error: + ssh_socket_close(session->socket); + session->alive = 0; + session->session_state=SSH_SESSION_STATE_ERROR; +- ++ SSH_LOG(SSH_LOG_WARN, "%s", ssh_get_error(session)); + } + + /** @internal +diff --git a/src/config.c b/src/config.c +index 8ed08d44..146beecf 100644 +--- a/src/config.c ++++ b/src/config.c +@@ -1165,7 +1165,7 @@ ssh_config_parse_line(ssh_session session, + keyword, count); + break; + case SOC_UNSUPPORTED: +- SSH_LOG(SSH_LOG_INFO, "Unsupported option: %s, line: %d", ++ SSH_LOG(SSH_LOG_RARE, "Unsupported option: %s, line: %d", + keyword, count); + break; + case SOC_UNKNOWN: +-- +2.38.1 + + +From dffde8c08cf3b30ca3d996dc784edc7279a38988 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Tue, 13 Sep 2022 12:13:38 +0200 +Subject: [PATCH 5/5] libssh.h: Update loglevel doc + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +Reviewed-by: Andreas Schneider +--- + include/libssh/libssh.h | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h +index 7857a77b..e17df2e9 100644 +--- a/include/libssh/libssh.h ++++ b/include/libssh/libssh.h +@@ -328,16 +328,16 @@ enum { + /** No logging at all + */ + SSH_LOG_NOLOG=0, +- /** Only warnings ++ /** Only unrecoverable errors + */ + SSH_LOG_WARNING, +- /** High level protocol information ++ /** Information for the users + */ + SSH_LOG_PROTOCOL, +- /** Lower level protocol infomations, packet level ++ /** Debug information, to see what is going on + */ + SSH_LOG_PACKET, +- /** Every function path ++ /** Trace information and recoverable error messages + */ + SSH_LOG_FUNCTIONS + }; +@@ -353,7 +353,7 @@ enum { + + /** No logging at all */ + #define SSH_LOG_NONE 0 +-/** Show only warnings */ ++/** Show only fatal warnings */ + #define SSH_LOG_WARN 1 + /** Get some information what's going on */ + #define SSH_LOG_INFO 2 +-- +2.38.1 + diff --git a/memory_leak.patch b/memory_leak.patch new file mode 100644 index 0000000..674cb35 --- /dev/null +++ b/memory_leak.patch @@ -0,0 +1,514 @@ +From 8795d8912c8a83aaf900c0260e252a35f64eb200 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Fri, 18 Nov 2022 17:22:46 +0100 +Subject: [PATCH] Fix memory leaks of bignums when openssl >= 3.0 + +The openssl 3.0 support has introduced some memory leaks at key build as +OSSL_PARAM_BLD_push_BN duplicates the bignum and does not save the pointer +itself. + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + include/libssh/dh.h | 2 +- + src/dh_crypto.c | 28 ++--- + src/pki_crypto.c | 262 ++++++++++++++++++++++++-------------------- + 3 files changed, 151 insertions(+), 141 deletions(-) + +diff --git a/include/libssh/dh.h b/include/libssh/dh.h +index 353dc233..9b9bb472 100644 +--- a/include/libssh/dh.h ++++ b/include/libssh/dh.h +@@ -53,7 +53,7 @@ int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer, + bignum *priv, bignum *pub); + #endif /* OPENSSL_VERSION_NUMBER */ + int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer, +- const bignum priv, const bignum pub); ++ bignum priv, bignum pub); + + int ssh_dh_compute_shared_secret(struct dh_ctx *ctx, int local, int remote, + bignum *dest); +diff --git a/src/dh_crypto.c b/src/dh_crypto.c +index a847c6a2..b578ddec 100644 +--- a/src/dh_crypto.c ++++ b/src/dh_crypto.c +@@ -154,12 +154,9 @@ int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer, + #endif /* OPENSSL_VERSION_NUMBER */ + + int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer, +- const bignum priv, const bignum pub) ++ bignum priv, bignum pub) + { +-#if OPENSSL_VERSION_NUMBER < 0x30000000L +- bignum priv_key = NULL; +- bignum pub_key = NULL; +-#else ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int rc; + OSSL_PARAM *params = NULL, *out_params = NULL, *merged_params = NULL; + OSSL_PARAM_BLD *param_bld = NULL; +@@ -172,7 +169,11 @@ int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer, + return SSH_ERROR; + } + +-#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++#if OPENSSL_VERSION_NUMBER < 0x30000000L ++ (void)DH_set0_key(ctx->keypair[peer], pub, priv); ++ ++ return SSH_OK; ++#else + rc = EVP_PKEY_todata(ctx->keypair[peer], EVP_PKEY_KEYPAIR, &out_params); + if (rc != 1) { + return SSH_ERROR; +@@ -195,35 +196,22 @@ int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer, + rc = SSH_ERROR; + goto out; + } +-#endif /* OPENSSL_VERSION_NUMBER */ + + if (priv) { +-#if OPENSSL_VERSION_NUMBER < 0x30000000L +- priv_key = priv; +-#else + rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, priv); + if (rc != 1) { + rc = SSH_ERROR; + goto out; + } +-#endif /* OPENSSL_VERSION_NUMBER */ + } + if (pub) { +-#if OPENSSL_VERSION_NUMBER < 0x30000000L +- pub_key = pub; +-#else + rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, pub); + if (rc != 1) { + rc = SSH_ERROR; + goto out; + } +-#endif /* OPENSSL_VERSION_NUMBER */ + } +-#if OPENSSL_VERSION_NUMBER < 0x30000000L +- (void)DH_set0_key(ctx->keypair[peer], pub_key, priv_key); + +- return SSH_OK; +-#else + params = OSSL_PARAM_BLD_to_param(param_bld); + if (params == NULL) { + rc = SSH_ERROR; +@@ -248,6 +236,8 @@ int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer, + + rc = SSH_OK; + out: ++ bignum_safe_free(priv); ++ bignum_safe_free(pub); + EVP_PKEY_CTX_free(evp_ctx); + OSSL_PARAM_free(out_params); + OSSL_PARAM_free(params); +diff --git a/src/pki_crypto.c b/src/pki_crypto.c +index 0a5003da..d3359e2d 100644 +--- a/src/pki_crypto.c ++++ b/src/pki_crypto.c +@@ -1492,18 +1492,18 @@ int pki_privkey_build_dss(ssh_key key, + ssh_string privkey) + { + int rc; +-#if OPENSSL_VERSION_NUMBER < 0x30000000L + BIGNUM *bp, *bq, *bg, *bpub_key, *bpriv_key; ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new(); ++ if (param_bld == NULL) { ++ return SSH_ERROR; ++ } + #else +- const BIGNUM *pb, *qb, *gb, *pubb, *privb; +- OSSL_PARAM_BLD *param_bld; +-#endif /* OPENSSL_VERSION_NUMBER */ +- +-#if OPENSSL_VERSION_NUMBER < 0x30000000L + key->dsa = DSA_new(); + if (key->dsa == NULL) { + return SSH_ERROR; + } ++#endif /* OPENSSL_VERSION_NUMBER */ + + bp = ssh_make_string_bn(p); + bq = ssh_make_string_bn(q); +@@ -1512,9 +1512,11 @@ int pki_privkey_build_dss(ssh_key key, + bpriv_key = ssh_make_string_bn(privkey); + if (bp == NULL || bq == NULL || + bg == NULL || bpub_key == NULL) { ++ rc = SSH_ERROR; + goto fail; + } + ++#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* Memory management of bp, qq and bg is transferred to DSA object */ + rc = DSA_set0_pqg(key->dsa, bp, bq, bg); + if (rc == 0) { +@@ -1532,39 +1534,43 @@ fail: + DSA_free(key->dsa); + return SSH_ERROR; + #else +- param_bld = OSSL_PARAM_BLD_new(); +- if (param_bld == NULL) +- goto err; +- +- pb = ssh_make_string_bn(p); +- qb = ssh_make_string_bn(q); +- gb = ssh_make_string_bn(g); +- pubb = ssh_make_string_bn(pubkey); +- privb = ssh_make_string_bn(privkey); +- +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, pb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, qb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, gb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, pubb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, privb); +- if (rc != 1) +- goto err; ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, bp); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, bq); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, bg); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, bpub_key); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, bpriv_key); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } + + rc = evp_build_pkey("DSA", param_bld, &(key->key), EVP_PKEY_KEYPAIR); ++ ++fail: + OSSL_PARAM_BLD_free(param_bld); ++ bignum_safe_free(bp); ++ bignum_safe_free(bq); ++ bignum_safe_free(bg); ++ bignum_safe_free(bpub_key); ++ bignum_safe_free(bpriv_key); + + return rc; +-err: +- OSSL_PARAM_BLD_free(param_bld); +- return -1; + #endif /* OPENSSL_VERSION_NUMBER */ + } + +@@ -1574,18 +1580,18 @@ int pki_pubkey_build_dss(ssh_key key, + ssh_string g, + ssh_string pubkey) { + int rc; +-#if OPENSSL_VERSION_NUMBER < 0x30000000L + BIGNUM *bp = NULL, *bq = NULL, *bg = NULL, *bpub_key = NULL; ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new(); ++ if (param_bld == NULL) { ++ return SSH_ERROR; ++ } + #else +- const BIGNUM *pb, *qb, *gb, *pubb; +- OSSL_PARAM_BLD *param_bld; +-#endif /* OPENSSL_VERSION_NUMBER */ +- +-#if OPENSSL_VERSION_NUMBER < 0x30000000L + key->dsa = DSA_new(); + if (key->dsa == NULL) { + return SSH_ERROR; + } ++#endif /* OPENSSL_VERSION_NUMBER */ + + bp = ssh_make_string_bn(p); + bq = ssh_make_string_bn(q); +@@ -1593,9 +1599,11 @@ int pki_pubkey_build_dss(ssh_key key, + bpub_key = ssh_make_string_bn(pubkey); + if (bp == NULL || bq == NULL || + bg == NULL || bpub_key == NULL) { ++ rc = SSH_ERROR; + goto fail; + } + ++#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* Memory management of bp, bq and bg is transferred to DSA object */ + rc = DSA_set0_pqg(key->dsa, bp, bq, bg); + if (rc == 0) { +@@ -1613,35 +1621,37 @@ fail: + DSA_free(key->dsa); + return SSH_ERROR; + #else +- param_bld = OSSL_PARAM_BLD_new(); +- if (param_bld == NULL) +- goto err; +- +- pb = ssh_make_string_bn(p); +- qb = ssh_make_string_bn(q); +- gb = ssh_make_string_bn(g); +- pubb = ssh_make_string_bn(pubkey); +- +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, pb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, qb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, gb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, pubb); +- if (rc != 1) +- goto err; ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, bp); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, bq); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, bg); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, bpub_key); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } + + rc = evp_build_pkey("DSA", param_bld, &(key->key), EVP_PKEY_PUBLIC_KEY); ++ ++fail: + OSSL_PARAM_BLD_free(param_bld); ++ bignum_safe_free(bp); ++ bignum_safe_free(bq); ++ bignum_safe_free(bg); ++ bignum_safe_free(bpub_key); + + return rc; +-err: +- OSSL_PARAM_BLD_free(param_bld); +- return -1; + #endif /* OPENSSL_VERSION_NUMBER */ + } + +@@ -1654,18 +1664,18 @@ int pki_privkey_build_rsa(ssh_key key, + ssh_string q) + { + int rc; +-#if OPENSSL_VERSION_NUMBER < 0x30000000L + BIGNUM *be, *bn, *bd/*, *biqmp*/, *bp, *bq; ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new(); ++ if (param_bld == NULL) { ++ return SSH_ERROR; ++ } + #else +- const BIGNUM *nb, *eb, *db, *pb, *qb; +- OSSL_PARAM_BLD *param_bld; +-#endif /* OPENSSL_VERSION_NUMBER */ +- +-#if OPENSSL_VERSION_NUMBER < 0x30000000L + key->rsa = RSA_new(); + if (key->rsa == NULL) { + return SSH_ERROR; + } ++#endif /* OPENSSL_VERSION_NUMBER */ + + bn = ssh_make_string_bn(n); + be = ssh_make_string_bn(e); +@@ -1675,9 +1685,11 @@ int pki_privkey_build_rsa(ssh_key key, + bq = ssh_make_string_bn(q); + if (be == NULL || bn == NULL || bd == NULL || + /*biqmp == NULL ||*/ bp == NULL || bq == NULL) { ++ rc = SSH_ERROR; + goto fail; + } + ++#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* Memory management of be, bn and bd is transferred to RSA object */ + rc = RSA_set0_key(key->rsa, bn, be, bd); + if (rc == 0) { +@@ -1702,41 +1714,49 @@ fail: + RSA_free(key->rsa); + return SSH_ERROR; + #else +- param_bld = OSSL_PARAM_BLD_new(); +- if (param_bld == NULL) +- goto err; +- +- nb = ssh_make_string_bn(n); +- eb = ssh_make_string_bn(e); +- db = ssh_make_string_bn(d); +- pb = ssh_make_string_bn(p); +- qb = ssh_make_string_bn(q); +- +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, nb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, eb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, db); +- if (rc != 1) +- goto err; ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, bn); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, be); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, bd); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } + + rc = evp_build_pkey("RSA", param_bld, &(key->key), EVP_PKEY_KEYPAIR); +- OSSL_PARAM_BLD_free(param_bld); ++ if (rc != SSH_OK) { ++ rc = SSH_ERROR; ++ goto fail; ++ } + +- rc = EVP_PKEY_set_bn_param(key->key, OSSL_PKEY_PARAM_RSA_FACTOR1, pb); +- if (rc != 1) +- goto err; ++ rc = EVP_PKEY_set_bn_param(key->key, OSSL_PKEY_PARAM_RSA_FACTOR1, bp); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } + +- rc = EVP_PKEY_set_bn_param(key->key, OSSL_PKEY_PARAM_RSA_FACTOR2, qb); +- if (rc != 1) +- goto err; ++ rc = EVP_PKEY_set_bn_param(key->key, OSSL_PKEY_PARAM_RSA_FACTOR2, bq); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } + +- return rc; +-err: ++fail: + OSSL_PARAM_BLD_free(param_bld); +- return -1; ++ bignum_safe_free(bn); ++ bignum_safe_free(be); ++ bignum_safe_free(bd); ++ bignum_safe_free(bp); ++ bignum_safe_free(bq); ++ ++ return rc; + #endif /* OPENSSL_VERSION_NUMBER */ + } + +@@ -1744,25 +1764,27 @@ int pki_pubkey_build_rsa(ssh_key key, + ssh_string e, + ssh_string n) { + int rc; +-#if OPENSSL_VERSION_NUMBER < 0x30000000L + BIGNUM *be = NULL, *bn = NULL; ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new(); ++ if (param_bld == NULL) { ++ return SSH_ERROR; ++ } + #else +- const BIGNUM *eb, *nb; +- OSSL_PARAM_BLD *param_bld; +-#endif /* OPENSSL_VERSION_NUMBER */ +- +-#if OPENSSL_VERSION_NUMBER < 0x30000000L + key->rsa = RSA_new(); + if (key->rsa == NULL) { + return SSH_ERROR; + } ++#endif /* OPENSSL_VERSION_NUMBER */ + + be = ssh_make_string_bn(e); + bn = ssh_make_string_bn(n); + if (be == NULL || bn == NULL) { ++ rc = SSH_ERROR; + goto fail; + } + ++#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* Memory management of bn and be is transferred to RSA object */ + rc = RSA_set0_key(key->rsa, bn, be, NULL); + if (rc == 0) { +@@ -1774,27 +1796,25 @@ fail: + RSA_free(key->rsa); + return SSH_ERROR; + #else +- nb = ssh_make_string_bn(n); +- eb = ssh_make_string_bn(e); +- +- param_bld = OSSL_PARAM_BLD_new(); +- if (param_bld == NULL) +- goto err; +- +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, nb); +- if (rc != 1) +- goto err; +- rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, eb); +- if (rc != 1) +- goto err; ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, bn); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } ++ rc = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, be); ++ if (rc != 1) { ++ rc = SSH_ERROR; ++ goto fail; ++ } + + rc = evp_build_pkey("RSA", param_bld, &(key->key), EVP_PKEY_PUBLIC_KEY); ++ ++fail: + OSSL_PARAM_BLD_free(param_bld); ++ bignum_safe_free(bn); ++ bignum_safe_free(be); + + return rc; +-err: +- OSSL_PARAM_BLD_free(param_bld); +- return -1; + #endif /* OPENSSL_VERSION_NUMBER */ + } + +-- +2.38.1 + diff --git a/options_apply.patch b/options_apply.patch new file mode 100644 index 0000000..7abcc0f --- /dev/null +++ b/options_apply.patch @@ -0,0 +1,968 @@ +From e7dd88167b68cbee7c603e8cd5fbb96ef3040c85 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Wed, 16 Nov 2022 10:40:38 +0100 +Subject: [PATCH 1/5] Add a placehohlder for non-expanded identities + +Expanding a string twice could lead to unwanted behaviour. +This solution creates a ssh_list (`opts.identites_non_exp`) to store the strings +before expansion and by using ssh_apply it moves the string to the +`opts.identities`. This way the expanded strings are separated. + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + include/libssh/session.h | 1 + + src/options.c | 86 +++++++++++++++++++++++++--------------- + src/session.c | 23 +++++++++-- + 3 files changed, 75 insertions(+), 35 deletions(-) + +diff --git a/include/libssh/session.h b/include/libssh/session.h +index d3e5787c..e22b0d67 100644 +--- a/include/libssh/session.h ++++ b/include/libssh/session.h +@@ -209,6 +209,7 @@ struct ssh_session_struct { + #endif + struct { + struct ssh_list *identity; ++ struct ssh_list *identity_non_exp; + char *username; + char *host; + char *bindaddr; /* bind the client to an ip addr */ +diff --git a/src/options.c b/src/options.c +index 56e09c65..bb085384 100644 +--- a/src/options.c ++++ b/src/options.c +@@ -52,7 +52,7 @@ + * @brief Duplicate the options of a session structure. + * + * If you make several sessions with the same options this is useful. You +- * cannot use twice the same option structure in ssh_session_connect. ++ * cannot use twice the same option structure in ssh_connect. + * + * @param src The session to use to copy the options. + * +@@ -61,13 +61,14 @@ + * + * @returns 0 on success, -1 on error with errno set. + * +- * @see ssh_session_connect() ++ * @see ssh_connect() + * @see ssh_free() + */ + int ssh_options_copy(ssh_session src, ssh_session *dest) + { + ssh_session new; + struct ssh_iterator *it = NULL; ++ struct ssh_list *list = NULL; + char *id = NULL; + int i; + +@@ -105,14 +106,15 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) + } + + /* Remove the default identities */ +- for (id = ssh_list_pop_head(char *, new->opts.identity); ++ for (id = ssh_list_pop_head(char *, new->opts.identity_non_exp); + id != NULL; +- id = ssh_list_pop_head(char *, new->opts.identity)) { ++ id = ssh_list_pop_head(char *, new->opts.identity_non_exp)) { + SAFE_FREE(id); + } + /* Copy the new identities from the source list */ +- if (src->opts.identity != NULL) { +- it = ssh_list_get_iterator(src->opts.identity); ++ list = new->opts.identity_non_exp; ++ it = ssh_list_get_iterator(src->opts.identity_non_exp); ++ for (i = 0; i < 2; i++) { + while (it) { + int rc; + +@@ -122,7 +124,7 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) + return -1; + } + +- rc = ssh_list_append(new->opts.identity, id); ++ rc = ssh_list_append(list, id); + if (rc < 0) { + free(id); + ssh_free(new); +@@ -130,6 +132,10 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) + } + it = it->next; + } ++ ++ /* copy the identity list if there is any already */ ++ list = new->opts.identity; ++ it = ssh_list_get_iterator(src->opts.identity); + } + + if (src->opts.sshdir != NULL) { +@@ -331,7 +337,7 @@ int ssh_options_set_algo(ssh_session session, + * Add a new identity file (const char *, format string) to + * the identity list.\n + * \n +- * By default identity, id_dsa and id_rsa are checked.\n ++ * By default id_rsa, id_ecdsa and id_ed25519 files are used.\n + * \n + * The identity used to authenticate with public key will be + * prepended to the list. +@@ -700,7 +706,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + if (q == NULL) { + return -1; + } +- rc = ssh_list_prepend(session->opts.identity, q); ++ if (session->opts.exp_flags & SSH_OPT_EXP_FLAG_IDENTITY) { ++ rc = ssh_list_append(session->opts.identity_non_exp, q); ++ } else { ++ rc = ssh_list_prepend(session->opts.identity_non_exp, q); ++ } + if (rc < 0) { + free(q); + return -1; +@@ -1202,7 +1212,7 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) { + * - SSH_OPTIONS_IDENTITY: + * Get the first identity file name (const char *).\n + * \n +- * By default identity, id_dsa and id_rsa are checked. ++ * By default id_rsa, id_ecdsa and id_ed25519 files are used. + * + * - SSH_OPTIONS_PROXYCOMMAND: + * Get the proxycommand necessary to log into the +@@ -1246,7 +1256,11 @@ int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value) + break; + } + case SSH_OPTIONS_IDENTITY: { +- struct ssh_iterator *it = ssh_list_get_iterator(session->opts.identity); ++ struct ssh_iterator *it; ++ it = ssh_list_get_iterator(session->opts.identity); ++ if (it == NULL) { ++ it = ssh_list_get_iterator(session->opts.identity_non_exp); ++ } + if (it == NULL) { + return SSH_ERROR; + } +@@ -1541,7 +1555,6 @@ out: + + int ssh_options_apply(ssh_session session) + { +- struct ssh_iterator *it; + char *tmp; + int rc; + +@@ -1586,15 +1599,17 @@ int ssh_options_apply(ssh_session session) + size_t plen = strlen(session->opts.ProxyCommand) + + 5 /* strlen("exec ") */; + +- p = malloc(plen + 1 /* \0 */); +- if (p == NULL) { +- return -1; +- } ++ if (strncmp(session->opts.ProxyCommand, "exec ", 5) != 0) { ++ p = malloc(plen + 1 /* \0 */); ++ if (p == NULL) { ++ return -1; ++ } + +- rc = snprintf(p, plen + 1, "exec %s", session->opts.ProxyCommand); +- if ((size_t)rc != plen) { +- free(p); +- return -1; ++ rc = snprintf(p, plen + 1, "exec %s", session->opts.ProxyCommand); ++ if ((size_t)rc != plen) { ++ free(p); ++ return -1; ++ } + } + + tmp = ssh_path_expand_escape(session, p); +@@ -1606,24 +1621,33 @@ int ssh_options_apply(ssh_session session) + session->opts.ProxyCommand = tmp; + } + +- for (it = ssh_list_get_iterator(session->opts.identity); +- it != NULL; +- it = it->next) { +- char *id = (char *) it->data; +- if (strncmp(id, "pkcs11:", 6) == 0) { ++ for (tmp = ssh_list_pop_head(char *, session->opts.identity_non_exp); ++ tmp != NULL; ++ tmp = ssh_list_pop_head(char *, session->opts.identity_non_exp)) { ++ char *id = tmp; ++ if (strncmp(id, "pkcs11:", 6) != 0) { + /* PKCS#11 URIs are using percent-encoding so we can not mix + * it with ssh expansion of ssh escape characters. +- * Skip these identities now, before we will have PKCS#11 support + */ +- continue; ++ tmp = ssh_path_expand_escape(session, id); ++ if (tmp == NULL) { ++ return -1; ++ } ++ free(id); + } +- tmp = ssh_path_expand_escape(session, id); +- if (tmp == NULL) { ++ ++ /* use append to keep the order at first call and use prepend ++ * to put anything that comes on the nth calls to the beginning */ ++ if (session->opts.exp_flags & SSH_OPT_EXP_FLAG_IDENTITY) { ++ rc = ssh_list_prepend(session->opts.identity, tmp); ++ } else { ++ rc = ssh_list_append(session->opts.identity, tmp); ++ } ++ if (rc != SSH_OK) { + return -1; + } +- free(id); +- it->data = tmp; + } ++ session->opts.exp_flags |= SSH_OPT_EXP_FLAG_IDENTITY; + + return 0; + } +diff --git a/src/session.c b/src/session.c +index 64e54957..34a492e4 100644 +--- a/src/session.c ++++ b/src/session.c +@@ -118,13 +118,17 @@ ssh_session ssh_new(void) + if (session->opts.identity == NULL) { + goto err; + } ++ session->opts.identity_non_exp = ssh_list_new(); ++ if (session->opts.identity_non_exp == NULL) { ++ goto err; ++ } + + id = strdup("%d/id_ed25519"); + if (id == NULL) { + goto err; + } + +- rc = ssh_list_append(session->opts.identity, id); ++ rc = ssh_list_append(session->opts.identity_non_exp, id); + if (rc == SSH_ERROR) { + goto err; + } +@@ -134,7 +138,7 @@ ssh_session ssh_new(void) + if (id == NULL) { + goto err; + } +- rc = ssh_list_append(session->opts.identity, id); ++ rc = ssh_list_append(session->opts.identity_non_exp, id); + if (rc == SSH_ERROR) { + goto err; + } +@@ -144,7 +148,7 @@ ssh_session ssh_new(void) + if (id == NULL) { + goto err; + } +- rc = ssh_list_append(session->opts.identity, id); ++ rc = ssh_list_append(session->opts.identity_non_exp, id); + if (rc == SSH_ERROR) { + goto err; + } +@@ -154,7 +158,7 @@ ssh_session ssh_new(void) + if (id == NULL) { + goto err; + } +- rc = ssh_list_append(session->opts.identity, id); ++ rc = ssh_list_append(session->opts.identity_non_exp, id); + if (rc == SSH_ERROR) { + goto err; + } +@@ -284,6 +288,17 @@ void ssh_free(ssh_session session) + ssh_list_free(session->opts.identity); + } + ++ if (session->opts.identity_non_exp) { ++ char *id; ++ ++ for (id = ssh_list_pop_head(char *, session->opts.identity_non_exp); ++ id != NULL; ++ id = ssh_list_pop_head(char *, session->opts.identity_non_exp)) { ++ SAFE_FREE(id); ++ } ++ ssh_list_free(session->opts.identity_non_exp); ++ } ++ + while ((b = ssh_list_pop_head(struct ssh_buffer_struct *, + session->out_queue)) != NULL) { + SSH_BUFFER_FREE(b); +-- +2.38.1 + + +From 364b4102d3056832d22753c73b37eabce50a6161 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Wed, 16 Nov 2022 11:03:30 +0100 +Subject: [PATCH 2/5] tests: Use opts.identites_non_exp not opts.identities + +The configuration of identities are first saved to `opts.identities_non_exp`, +then moved to `opts.identities` after calling ssh_options_apply and expanding +the identity strings. These tests are testing against the proper configuration + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + tests/client/torture_auth.c | 114 +++++++++++++++++++++++++++++ + tests/client/torture_auth_pkcs11.c | 2 +- + tests/unittests/torture_config.c | 3 +- + tests/unittests/torture_options.c | 14 ++-- + 4 files changed, 124 insertions(+), 9 deletions(-) + +diff --git a/tests/client/torture_auth.c b/tests/client/torture_auth.c +index 79dbd4a7..deb095ef 100644 +--- a/tests/client/torture_auth.c ++++ b/tests/client/torture_auth.c +@@ -686,6 +686,120 @@ static void torture_auth_agent_nonblocking(void **state) { + assert_ssh_return_code(session, rc); + } + ++static void torture_auth_agent_identities_only(void **state) ++{ ++ struct torture_state *s = *state; ++ ssh_session session = s->ssh.session; ++ char bob_ssh_key[1024]; ++ struct passwd *pwd; ++ int rc; ++ int identities_only = 1; ++ char *id; ++ ++ pwd = getpwnam("bob"); ++ assert_non_null(pwd); ++ ++ snprintf(bob_ssh_key, ++ sizeof(bob_ssh_key), ++ "%s/.ssh/id_rsa", ++ pwd->pw_dir); ++ ++ if (!ssh_agent_is_running(session)){ ++ print_message("*** Agent not running. Test ignored\n"); ++ return; ++ } ++ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE); ++ assert_int_equal(rc, SSH_OK); ++ ++ rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, &identities_only); ++ assert_int_equal(rc, SSH_OK); ++ ++ /* Remove the default identities */ ++ while ((id = ssh_list_pop_head(char *, session->opts.identity_non_exp)) != NULL) { ++ SAFE_FREE(id); ++ } ++ ++ rc = ssh_connect(session); ++ assert_int_equal(rc, SSH_OK); ++ ++ rc = ssh_userauth_none(session, NULL); ++ /* This request should return a SSH_REQUEST_DENIED error */ ++ if (rc == SSH_ERROR) { ++ assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED); ++ } ++ rc = ssh_userauth_list(session, NULL); ++ assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY); ++ ++ /* Should fail as key is not in config */ ++ rc = ssh_userauth_agent(session, NULL); ++ assert_ssh_return_code_equal(session, rc, SSH_AUTH_DENIED); ++ ++ /* Re-add a key */ ++ rc = ssh_list_append(session->opts.identity, strdup(bob_ssh_key)); ++ assert_int_equal(rc, SSH_OK); ++ ++ /* Should succeed as key now in config */ ++ rc = ssh_userauth_agent(session, NULL); ++ assert_ssh_return_code(session, rc); ++} ++ ++static void torture_auth_agent_identities_only_protected(void **state) ++{ ++ struct torture_state *s = *state; ++ ssh_session session = s->ssh.session; ++ char bob_ssh_key[1024]; ++ struct passwd *pwd; ++ int rc; ++ int identities_only = 1; ++ char *id; ++ ++ pwd = getpwnam("bob"); ++ assert_non_null(pwd); ++ ++ snprintf(bob_ssh_key, ++ sizeof(bob_ssh_key), ++ "%s/.ssh/id_rsa_protected", ++ pwd->pw_dir); ++ ++ if (!ssh_agent_is_running(session)){ ++ print_message("*** Agent not running. Test ignored\n"); ++ return; ++ } ++ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE); ++ assert_int_equal(rc, SSH_OK); ++ ++ rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, &identities_only); ++ assert_int_equal(rc, SSH_OK); ++ ++ /* Remove the default identities */ ++ while ((id = ssh_list_pop_head(char *, session->opts.identity_non_exp)) != NULL) { ++ SAFE_FREE(id); ++ } ++ ++ rc = ssh_connect(session); ++ assert_int_equal(rc, SSH_OK); ++ ++ rc = ssh_userauth_none(session, NULL); ++ /* This request should return a SSH_REQUEST_DENIED error */ ++ if (rc == SSH_ERROR) { ++ assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED); ++ } ++ rc = ssh_userauth_list(session, NULL); ++ assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY); ++ ++ /* Should fail as key is not in config */ ++ rc = ssh_userauth_agent(session, NULL); ++ assert_ssh_return_code_equal(session, rc, SSH_AUTH_DENIED); ++ ++ /* Re-add a key */ ++ rc = ssh_list_append(session->opts.identity, strdup(bob_ssh_key)); ++ assert_int_equal(rc, SSH_OK); ++ ++ /* Should succeed as key now in config */ ++ rc = ssh_userauth_agent(session, NULL); ++ assert_ssh_return_code(session, rc); ++} ++ + static void torture_auth_cert(void **state) { + struct torture_state *s = *state; + ssh_session session = s->ssh.session; +diff --git a/tests/client/torture_auth_pkcs11.c b/tests/client/torture_auth_pkcs11.c +index ee97bff4..e75fea0e 100644 +--- a/tests/client/torture_auth_pkcs11.c ++++ b/tests/client/torture_auth_pkcs11.c +@@ -196,7 +196,7 @@ static void torture_auth_autopubkey(void **state, const char *obj_name, const ch + + rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, priv_uri); + assert_int_equal(rc, SSH_OK); +- assert_string_equal(session->opts.identity->root->data, priv_uri); ++ assert_string_equal(session->opts.identity_non_exp->root->data, priv_uri); + + rc = ssh_connect(session); + assert_int_equal(rc, SSH_OK); +diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c +index 354adc2f..100e68f6 100644 +--- a/tests/unittests/torture_config.c ++++ b/tests/unittests/torture_config.c +@@ -2078,7 +2078,8 @@ static void torture_config_identity(void **state) + + _parse_config(session, NULL, LIBSSH_TESTCONFIG_STRING13, SSH_OK); + +- it = ssh_list_get_iterator(session->opts.identity); ++ /* The identities are first added to this temporary list before expanding */ ++ it = ssh_list_get_iterator(session->opts.identity_non_exp); + assert_non_null(it); + id = it->data; + /* The identities are prepended to the list so we start with second one */ +diff --git a/tests/unittests/torture_options.c b/tests/unittests/torture_options.c +index dc4df383..3be2de8a 100644 +--- a/tests/unittests/torture_options.c ++++ b/tests/unittests/torture_options.c +@@ -406,12 +406,12 @@ static void torture_options_set_identity(void **state) { + + rc = ssh_options_set(session, SSH_OPTIONS_ADD_IDENTITY, "identity1"); + assert_true(rc == 0); +- assert_string_equal(session->opts.identity->root->data, "identity1"); ++ assert_string_equal(session->opts.identity_non_exp->root->data, "identity1"); + + rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, "identity2"); + assert_true(rc == 0); +- assert_string_equal(session->opts.identity->root->data, "identity2"); +- assert_string_equal(session->opts.identity->root->next->data, "identity1"); ++ assert_string_equal(session->opts.identity_non_exp->root->data, "identity2"); ++ assert_string_equal(session->opts.identity_non_exp->root->next->data, "identity1"); + } + + static void torture_options_get_identity(void **state) { +@@ -429,7 +429,7 @@ static void torture_options_get_identity(void **state) { + + rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, "identity2"); + assert_int_equal(rc, SSH_OK); +- assert_string_equal(session->opts.identity->root->data, "identity2"); ++ assert_string_equal(session->opts.identity_non_exp->root->data, "identity2"); + rc = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &identity); + assert_int_equal(rc, SSH_OK); + assert_non_null(identity); +@@ -867,9 +867,9 @@ static void torture_options_copy(void **state) + assert_non_null(new); + + /* Check the identities match */ +- it = ssh_list_get_iterator(session->opts.identity); ++ it = ssh_list_get_iterator(session->opts.identity_non_exp); + assert_non_null(it); +- it2 = ssh_list_get_iterator(new->opts.identity); ++ it2 = ssh_list_get_iterator(new->opts.identity_non_exp); + assert_non_null(it2); + while (it != NULL && it2 != NULL) { + assert_string_equal(it->data, it2->data); +@@ -956,7 +956,7 @@ static void torture_options_getopt(void **state) + "aes128-ctr"); + assert_string_equal(session->opts.wanted_methods[SSH_CRYPT_S_C], + "aes128-ctr"); +- assert_string_equal(session->opts.identity->root->data, "id_rsa"); ++ assert_string_equal(session->opts.identity_non_exp->root->data, "id_rsa"); + #ifdef WITH_ZLIB + assert_string_equal(session->opts.wanted_methods[SSH_COMP_C_S], + "zlib@openssh.com,zlib,none"); +-- +2.38.1 + + +From 868e2d7c28b914b3d6f516cfc1e31d79aaddec1c Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Wed, 16 Nov 2022 16:51:02 +0100 +Subject: [PATCH 3/5] Add flags for escape expand operation + +Calling `ssh_options_apply` more times can result in an unwanted behaviour of +expanding the escape characters more times. Adding flags to check if the +expansion was already done on the current string variables. + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + include/libssh/session.h | 7 ++++ + src/options.c | 91 ++++++++++++++++++++++++---------------- + src/session.c | 2 + + 3 files changed, 63 insertions(+), 37 deletions(-) + +diff --git a/include/libssh/session.h b/include/libssh/session.h +index e22b0d67..cf219c2a 100644 +--- a/include/libssh/session.h ++++ b/include/libssh/session.h +@@ -93,6 +93,12 @@ enum ssh_pending_call_e { + #define SSH_OPT_FLAG_KBDINT_AUTH 0x4 + #define SSH_OPT_FLAG_GSSAPI_AUTH 0x8 + ++/* Escape expansion of different variables */ ++#define SSH_OPT_EXP_FLAG_KNOWNHOSTS 0x1 ++#define SSH_OPT_EXP_FLAG_GLOBAL_KNOWNHOSTS 0x2 ++#define SSH_OPT_EXP_FLAG_PROXYCOMMAND 0x4 ++#define SSH_OPT_EXP_FLAG_IDENTITY 0x8 ++ + /* extensions flags */ + /* negotiation enabled */ + #define SSH_EXT_NEGOTIATION 0x01 +@@ -232,6 +238,7 @@ struct ssh_session_struct { + char *gss_client_identity; + int gss_delegate_creds; + int flags; ++ int exp_flags; + int nodelay; + bool config_processed; + uint8_t options_seen[SOC_MAX]; +diff --git a/src/options.c b/src/options.c +index bb085384..c566244b 100644 +--- a/src/options.c ++++ b/src/options.c +@@ -730,6 +730,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_oom(session); + return -1; + } ++ session->opts.exp_flags &= ~SSH_OPT_EXP_FLAG_KNOWNHOSTS; + } + break; + case SSH_OPTIONS_GLOBAL_KNOWNHOSTS: +@@ -751,6 +752,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_oom(session); + return -1; + } ++ session->opts.exp_flags &= ~SSH_OPT_EXP_FLAG_GLOBAL_KNOWNHOSTS; + } + break; + case SSH_OPTIONS_TIMEOUT: +@@ -1014,6 +1016,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + return -1; + } + session->opts.ProxyCommand = q; ++ session->opts.exp_flags &= ~SSH_OPT_EXP_FLAG_PROXYCOMMAND; + } + } + break; +@@ -1572,53 +1575,67 @@ int ssh_options_apply(ssh_session session) + } + } + +- if (session->opts.knownhosts == NULL) { +- tmp = ssh_path_expand_escape(session, "%d/known_hosts"); +- } else { +- tmp = ssh_path_expand_escape(session, session->opts.knownhosts); +- } +- if (tmp == NULL) { +- return -1; ++ if ((session->opts.exp_flags & SSH_OPT_EXP_FLAG_KNOWNHOSTS) == 0) { ++ if (session->opts.knownhosts == NULL) { ++ tmp = ssh_path_expand_escape(session, "%d/known_hosts"); ++ } else { ++ tmp = ssh_path_expand_escape(session, session->opts.knownhosts); ++ } ++ if (tmp == NULL) { ++ return -1; ++ } ++ free(session->opts.knownhosts); ++ session->opts.knownhosts = tmp; ++ session->opts.exp_flags |= SSH_OPT_EXP_FLAG_KNOWNHOSTS; + } +- free(session->opts.knownhosts); +- session->opts.knownhosts = tmp; + +- if (session->opts.global_knownhosts == NULL) { +- tmp = strdup("/etc/ssh/ssh_known_hosts"); +- } else { +- tmp = ssh_path_expand_escape(session, session->opts.global_knownhosts); +- } +- if (tmp == NULL) { +- return -1; ++ if ((session->opts.exp_flags & SSH_OPT_EXP_FLAG_GLOBAL_KNOWNHOSTS) == 0) { ++ if (session->opts.global_knownhosts == NULL) { ++ tmp = strdup("/etc/ssh/ssh_known_hosts"); ++ } else { ++ tmp = ssh_path_expand_escape(session, ++ session->opts.global_knownhosts); ++ } ++ if (tmp == NULL) { ++ return -1; ++ } ++ free(session->opts.global_knownhosts); ++ session->opts.global_knownhosts = tmp; ++ session->opts.exp_flags |= SSH_OPT_EXP_FLAG_GLOBAL_KNOWNHOSTS; + } +- free(session->opts.global_knownhosts); +- session->opts.global_knownhosts = tmp; + +- if (session->opts.ProxyCommand != NULL) { +- char *p = NULL; +- size_t plen = strlen(session->opts.ProxyCommand) + +- 5 /* strlen("exec ") */; + +- if (strncmp(session->opts.ProxyCommand, "exec ", 5) != 0) { +- p = malloc(plen + 1 /* \0 */); +- if (p == NULL) { +- return -1; +- } ++ if ((session->opts.exp_flags & SSH_OPT_EXP_FLAG_PROXYCOMMAND) == 0) { ++ if (session->opts.ProxyCommand != NULL) { ++ char *p = NULL; ++ size_t plen = strlen(session->opts.ProxyCommand) + ++ 5 /* strlen("exec ") */; ++ ++ if (strncmp(session->opts.ProxyCommand, "exec ", 5) != 0) { ++ p = malloc(plen + 1 /* \0 */); ++ if (p == NULL) { ++ return -1; ++ } + +- rc = snprintf(p, plen + 1, "exec %s", session->opts.ProxyCommand); +- if ((size_t)rc != plen) { ++ rc = snprintf(p, plen + 1, "exec %s", session->opts.ProxyCommand); ++ if ((size_t)rc != plen) { ++ free(p); ++ return -1; ++ } ++ tmp = ssh_path_expand_escape(session, p); + free(p); +- return -1; ++ } else { ++ tmp = ssh_path_expand_escape(session, ++ session->opts.ProxyCommand); + } +- } + +- tmp = ssh_path_expand_escape(session, p); +- free(p); +- if (tmp == NULL) { +- return -1; ++ if (tmp == NULL) { ++ return -1; ++ } ++ free(session->opts.ProxyCommand); ++ session->opts.ProxyCommand = tmp; ++ session->opts.exp_flags |= SSH_OPT_EXP_FLAG_PROXYCOMMAND; + } +- free(session->opts.ProxyCommand); +- session->opts.ProxyCommand = tmp; + } + + for (tmp = ssh_list_pop_head(char *, session->opts.identity_non_exp); +diff --git a/src/session.c b/src/session.c +index 34a492e4..06f6a26f 100644 +--- a/src/session.c ++++ b/src/session.c +@@ -114,6 +114,8 @@ ssh_session ssh_new(void) + SSH_OPT_FLAG_KBDINT_AUTH | + SSH_OPT_FLAG_GSSAPI_AUTH; + ++ session->opts.exp_flags = 0; ++ + session->opts.identity = ssh_list_new(); + if (session->opts.identity == NULL) { + goto err; +-- +2.38.1 + + +From 8849d0d89de7151a1e516ec373f570ba4678dde9 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Wed, 16 Nov 2022 17:17:14 +0100 +Subject: [PATCH 4/5] torture_options.c: Add identity test for ssh_options_copy + +Test if the ssh_options_apply is called on session before ssh_options_copy, +then `opts.identity` ssh_list will be copied + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + tests/unittests/torture_options.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/tests/unittests/torture_options.c b/tests/unittests/torture_options.c +index 3be2de8a..907cc8df 100644 +--- a/tests/unittests/torture_options.c ++++ b/tests/unittests/torture_options.c +@@ -918,6 +918,34 @@ static void torture_options_copy(void **state) + sizeof(session->opts.options_seen)); + + ssh_free(new); ++ ++ /* test if ssh_options_apply was called before ssh_options_copy ++ * the opts.identity list gets copied (percent expanded list) */ ++ rv = ssh_options_apply(session); ++ assert_ssh_return_code(session, rv); ++ ++ rv = ssh_options_copy(session, &new); ++ assert_ssh_return_code(session, rv); ++ assert_non_null(new); ++ ++ it = ssh_list_get_iterator(session->opts.identity_non_exp); ++ assert_null(it); ++ it2 = ssh_list_get_iterator(new->opts.identity_non_exp); ++ assert_null(it2); ++ ++ it = ssh_list_get_iterator(session->opts.identity); ++ assert_non_null(it); ++ it2 = ssh_list_get_iterator(new->opts.identity); ++ assert_non_null(it2); ++ while (it != NULL && it2 != NULL) { ++ assert_string_equal(it->data, it2->data); ++ it = it->next; ++ it2 = it2->next; ++ } ++ assert_null(it); ++ assert_null(it2); ++ ++ ssh_free(new); + } + + #define EXECUTABLE_NAME "test-exec" +-- +2.38.1 + + +From 88ef38bd1d95b07be4fa818462fb56fcca84cc5a Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Wed, 16 Nov 2022 17:18:49 +0100 +Subject: [PATCH 5/5] torture_options.c: Add test for ssh_options_apply + +Test that ssh_options_apply can be called multiple times without expanding +escape characters more than once. If the options are updated after calling +ssh_options_apply keep the last options. + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + tests/unittests/torture_options.c | 165 ++++++++++++++++++++++++++++++ + 1 file changed, 165 insertions(+) + +diff --git a/tests/unittests/torture_options.c b/tests/unittests/torture_options.c +index 907cc8df..ea63b45e 100644 +--- a/tests/unittests/torture_options.c ++++ b/tests/unittests/torture_options.c +@@ -1332,6 +1332,170 @@ static void torture_options_caret_sign(void **state) + free(awaited); + } + ++static void torture_options_apply (void **state) { ++ ssh_session session = *state; ++ struct ssh_list *awaited_list = NULL; ++ struct ssh_iterator *it1 = NULL, *it2 = NULL; ++ char *id = NULL; ++ int rc; ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_KNOWNHOSTS, ++ "%%d/.ssh/known_hosts"); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_GLOBAL_KNOWNHOSTS, ++ "/etc/%%u/libssh/known_hosts"); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_PROXYCOMMAND, ++ "exec echo \"Hello libssh %%d!\""); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_ADD_IDENTITY, ++ "%%d/do_not_expand"); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_apply(session); ++ assert_ssh_return_code(session, rc); ++ ++ /* check that the values got expanded */ ++ assert_true(session->opts.exp_flags & SSH_OPT_EXP_FLAG_KNOWNHOSTS); ++ assert_true(session->opts.exp_flags & SSH_OPT_EXP_FLAG_GLOBAL_KNOWNHOSTS); ++ assert_true(session->opts.exp_flags & SSH_OPT_EXP_FLAG_PROXYCOMMAND); ++ assert_true(ssh_list_count(session->opts.identity_non_exp) == 0); ++ assert_true(ssh_list_count(session->opts.identity) > 0); ++ ++ /* should not change anything calling it again */ ++ rc = ssh_options_apply(session); ++ assert_ssh_return_code(session, rc); ++ ++ /* check that the expansion was done only once */ ++ assert_string_equal(session->opts.knownhosts, "%d/.ssh/known_hosts"); ++ assert_string_equal(session->opts.global_knownhosts, ++ "/etc/%u/libssh/known_hosts"); ++ /* no exec should be added if there already is one */ ++ assert_string_equal(session->opts.ProxyCommand, ++ "exec echo \"Hello libssh %d!\""); ++ assert_string_equal(session->opts.identity->root->data, ++ "%d/do_not_expand"); ++ ++ /* apply should keep the freshest setting */ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_KNOWNHOSTS, ++ "hello there"); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_GLOBAL_KNOWNHOSTS, ++ "lorem ipsum"); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_PROXYCOMMAND, ++ "mission_impossible"); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_ADD_IDENTITY, ++ "007"); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_ADD_IDENTITY, ++ "3"); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_ADD_IDENTITY, ++ "2"); ++ assert_ssh_return_code(session, rc); ++ ++ rc = ssh_options_set(session, ++ SSH_OPTIONS_ADD_IDENTITY, ++ "1"); ++ assert_ssh_return_code(session, rc); ++ ++ /* check that flags show need of escape expansion */ ++ assert_false(session->opts.exp_flags & SSH_OPT_EXP_FLAG_KNOWNHOSTS); ++ assert_false(session->opts.exp_flags & SSH_OPT_EXP_FLAG_GLOBAL_KNOWNHOSTS); ++ assert_false(session->opts.exp_flags & SSH_OPT_EXP_FLAG_PROXYCOMMAND); ++ assert_false(ssh_list_count(session->opts.identity_non_exp) == 0); ++ ++ rc = ssh_options_apply(session); ++ assert_ssh_return_code(session, rc); ++ ++ /* check that the values got expanded */ ++ assert_true(session->opts.exp_flags & SSH_OPT_EXP_FLAG_KNOWNHOSTS); ++ assert_true(session->opts.exp_flags & SSH_OPT_EXP_FLAG_GLOBAL_KNOWNHOSTS); ++ assert_true(session->opts.exp_flags & SSH_OPT_EXP_FLAG_PROXYCOMMAND); ++ assert_true(ssh_list_count(session->opts.identity_non_exp) == 0); ++ ++ assert_string_equal(session->opts.knownhosts, "hello there"); ++ assert_string_equal(session->opts.global_knownhosts, "lorem ipsum"); ++ /* check that the "exec " was added at the beginning */ ++ assert_string_equal(session->opts.ProxyCommand, "exec mission_impossible"); ++ assert_string_equal(session->opts.identity->root->data, "1"); ++ ++ /* check the order of the identity files after double expansion */ ++ awaited_list = ssh_list_new(); ++ /* append the new data in order */ ++ id = strdup("1"); ++ rc = ssh_list_append(awaited_list, id); ++ assert_int_equal(rc, SSH_OK); ++ id = strdup("2"); ++ rc = ssh_list_append(awaited_list, id); ++ assert_int_equal(rc, SSH_OK); ++ id = strdup("3"); ++ rc = ssh_list_append(awaited_list, id); ++ assert_int_equal(rc, SSH_OK); ++ id = strdup("007"); ++ rc = ssh_list_append(awaited_list, id); ++ assert_int_equal(rc, SSH_OK); ++ id = strdup("%d/do_not_expand"); ++ rc = ssh_list_append(awaited_list, id); ++ assert_int_equal(rc, SSH_OK); ++ /* append the defaults; this list is copied from ssh_new@src/session.c */ ++ id = ssh_path_expand_escape(session, "%d/id_ed25519"); ++ rc = ssh_list_append(awaited_list, id); ++ assert_int_equal(rc, SSH_OK); ++#ifdef HAVE_ECC ++ id = ssh_path_expand_escape(session, "%d/id_ecdsa"); ++ rc = ssh_list_append(awaited_list, id); ++ assert_int_equal(rc, SSH_OK); ++#endif ++ id = ssh_path_expand_escape(session, "%d/id_rsa"); ++ rc = ssh_list_append(awaited_list, id); ++ assert_int_equal(rc, SSH_OK); ++#ifdef HAVE_DSA ++ id = ssh_path_expand_escape(session, "%d/id_dsa"); ++ rc = ssh_list_append(awaited_list, id); ++ assert_int_equal(rc, SSH_OK); ++#endif ++ ++ assert_int_equal(ssh_list_count(awaited_list), ++ ssh_list_count(session->opts.identity)); ++ ++ it1 = ssh_list_get_iterator(awaited_list); ++ assert_non_null(it1); ++ it2 = ssh_list_get_iterator(session->opts.identity); ++ assert_non_null(it2); ++ while (it1 != NULL && it2 != NULL) { ++ assert_string_equal(it1->data, it2->data); ++ ++ free((void*)it1->data); ++ it1 = it1->next; ++ it2 = it2->next; ++ } ++ assert_null(it1); ++ assert_null(it2); ++ ++ ssh_list_free(awaited_list); ++} ++ + #ifdef WITH_SERVER + const char template[] = "temp_dir_XXXXXX"; + +@@ -2132,6 +2296,7 @@ int torture_run_tests(void) { + setup, teardown), + cmocka_unit_test_setup_teardown(torture_options_caret_sign, + setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_options_apply, setup, teardown), + }; + + #ifdef WITH_SERVER +-- +2.38.1 + diff --git a/plus_sign.patch b/plus_sign.patch new file mode 100644 index 0000000..7f01208 --- /dev/null +++ b/plus_sign.patch @@ -0,0 +1,1653 @@ +From 02d98a940fe82da29dc2e88cbd1609dc873d249f Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Mon, 7 Nov 2022 13:08:02 +0100 +Subject: [PATCH 1/6] tokens: Add low-level function to exlclude, prepend lists + +These functions are needed for openssh -,^ features. + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + include/libssh/token.h | 8 +++ + src/token.c | 141 +++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 145 insertions(+), 4 deletions(-) + +diff --git a/include/libssh/token.h b/include/libssh/token.h +index 9896fb06..2d07f8c4 100644 +--- a/include/libssh/token.h ++++ b/include/libssh/token.h +@@ -45,4 +45,12 @@ char *ssh_remove_duplicates(const char *list); + + char *ssh_append_without_duplicates(const char *list, + const char *appended_list); ++char *ssh_prefix_without_duplicates(const char *list, ++ const char *prefixed_list); ++char *ssh_remove_all_matching(const char *list, ++ const char *remove_list); ++ ++#ifdef __cplusplus ++} ++#endif + #endif /* TOKEN_H_ */ +diff --git a/src/token.c b/src/token.c +index 0924d3bd..2e26c562 100644 +--- a/src/token.c ++++ b/src/token.c +@@ -376,6 +376,7 @@ char *ssh_append_without_duplicates(const char *list, + { + size_t concat_len = 0; + char *ret = NULL, *concat = NULL; ++ int rc = 0; + + if (list != NULL) { + concat_len = strlen(list); +@@ -396,12 +397,144 @@ char *ssh_append_without_duplicates(const char *list, + return NULL; + } + ++ rc = snprintf(concat, concat_len, "%s%s%s", ++ list == NULL ? "" : list, ++ list == NULL ? "" : ",", ++ appended_list == NULL ? "" : appended_list); ++ if (rc < 0) { ++ SAFE_FREE(concat); ++ return NULL; ++ } ++ ++ ret = ssh_remove_duplicates(concat); ++ ++ SAFE_FREE(concat); ++ ++ return ret; ++} ++ ++/** ++ * @internal ++ * ++ * @brief Given two strings containing lists of tokens, return a newly ++ * allocated string containing the elements of the first list without the ++ * elements of the second list. The order of the elements will be preserved. ++ * ++ * @param[in] list The first list ++ * @param[in] remove_list The list to be removed ++ * ++ * @return A newly allocated copy list containing elements of the ++ * list without the elements of remove_list; NULL in case of error. ++ */ ++char *ssh_remove_all_matching(const char *list, ++ const char *remove_list) ++{ ++ struct ssh_tokens_st *l_tok = NULL, *r_tok = NULL; ++ int i, j, cmp; ++ char *ret = NULL; ++ size_t len, pos = 0; ++ bool exclude; ++ ++ if ((list == NULL)) { ++ return NULL; ++ } ++ if (remove_list == NULL) { ++ return strdup (list); ++ } ++ ++ l_tok = ssh_tokenize(list, ','); ++ if (l_tok == NULL) { ++ goto out; ++ } ++ ++ r_tok = ssh_tokenize(remove_list, ','); ++ if (r_tok == NULL) { ++ goto out; ++ } ++ ++ ret = calloc(1, strlen(list) + 1); ++ if (ret == NULL) { ++ return NULL; ++ } ++ ++ for (i = 0; l_tok->tokens[i]; i++) { ++ exclude = false; ++ for (j = 0; r_tok->tokens[j]; j++) { ++ cmp = strcmp(l_tok->tokens[i], r_tok->tokens[j]); ++ if (cmp == 0) { ++ exclude = true; ++ break; ++ } ++ } ++ if (exclude == false) { ++ if (pos != 0) { ++ ret[pos] = ','; ++ pos++; ++ } ++ ++ len = strlen(l_tok->tokens[i]); ++ memcpy(&ret[pos], l_tok->tokens[i], len); ++ pos += len; ++ } ++ } ++ ++ if (ret[0] == '\0') { ++ SAFE_FREE(ret); ++ } ++ ++out: ++ ssh_tokens_free(l_tok); ++ ssh_tokens_free(r_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 prefixed at ++ * the beginning of the second list, without duplicates. ++ * ++ * @param[in] list The first list ++ * @param[in] prefixed_list The list to use as a prefix ++ * ++ * @return A newly allocated list containing all the elements ++ * of the list prefixed with the elements of the prefixed_list without ++ * duplicates; NULL in case of error. ++ */ ++char *ssh_prefix_without_duplicates(const char *list, ++ const char *prefixed_list) ++{ ++ size_t concat_len = 0; ++ char *ret = NULL, *concat = NULL; ++ int rc = 0; ++ + if (list != NULL) { +- strcpy(concat, list); +- strncat(concat, ",", concat_len - strlen(concat) - 1); ++ concat_len = strlen(list); + } +- if (appended_list != NULL) { +- strncat(concat, appended_list, concat_len - strlen(concat) - 1); ++ ++ if (prefixed_list != NULL) { ++ concat_len += strlen(prefixed_list); ++ } ++ ++ if (concat_len == 0) { ++ return NULL; ++ } ++ ++ /* Add room for ending '\0' and for middle ',' */ ++ concat_len += 2; ++ concat = calloc(concat_len, 1); ++ if (concat == NULL) { ++ return NULL; ++ } ++ ++ rc = snprintf(concat, concat_len, "%s%s%s", ++ prefixed_list == NULL ? "" : prefixed_list, ++ prefixed_list == NULL ? "" : ",", ++ list == NULL ? "" : list); ++ if (rc < 0) { ++ SAFE_FREE(concat); ++ return NULL; + } + + ret = ssh_remove_duplicates(concat); +-- +2.38.1 + + +From 2b33a46804ee76d7f7c651aad71fd26160d4a3cf Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Fri, 11 Nov 2022 17:47:22 +0100 +Subject: [PATCH 2/6] torture_tokens.c: Add tests for new token functions + +Functions `ssh_remove_all_matching` and `ssh_prefix_without_duplicates` were +added; a little test suite will suite them. + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + tests/unittests/torture_tokens.c | 64 ++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +diff --git a/tests/unittests/torture_tokens.c b/tests/unittests/torture_tokens.c +index 6b52b847..438538de 100644 +--- a/tests/unittests/torture_tokens.c ++++ b/tests/unittests/torture_tokens.c +@@ -265,6 +265,68 @@ static void torture_append_without_duplicate(UNUSED_PARAM(void **state)) + } + } + ++static void torture_remove_all_matching (UNUSED_PARAM(void** state)) { ++ char *p; ++ ++ p = ssh_remove_all_matching(NULL, NULL); ++ assert_null(p); ++ ++ p = ssh_remove_all_matching("don't remove", NULL); ++ assert_non_null(p); ++ assert_string_equal(p, "don't remove"); ++ free(p); ++ ++ p = ssh_remove_all_matching("a,b,c", "b"); ++ assert_non_null(p); ++ assert_string_equal(p, "a,c"); ++ free(p); ++ ++ p = ssh_remove_all_matching("a,b,c", "a,b"); ++ assert_non_null(p); ++ assert_string_equal(p, "c"); ++ free(p); ++ ++ p = ssh_remove_all_matching("a,b,c", "d"); ++ assert_non_null(p); ++ assert_string_equal(p, "a,b,c"); ++ free(p); ++ ++ p = ssh_remove_all_matching("a,b,c", "a,b,c"); ++ assert_null(p); ++} ++ ++static void torture_prefix_without_duplicates (UNUSED_PARAM(void** state)) { ++ char *p; ++ ++ p = ssh_prefix_without_duplicates(NULL, NULL); ++ assert_null(p); ++ ++ p = ssh_prefix_without_duplicates("a,b,c", NULL); ++ assert_non_null(p); ++ assert_string_equal(p, "a,b,c"); ++ free(p); ++ ++ p = ssh_prefix_without_duplicates("a,b,c", "a"); ++ assert_non_null(p); ++ assert_string_equal(p, "a,b,c"); ++ free(p); ++ ++ p = ssh_prefix_without_duplicates("a,b,c", "b"); ++ assert_non_null(p); ++ assert_string_equal(p, "b,a,c"); ++ free(p); ++ ++ p = ssh_prefix_without_duplicates("a,b,c", "x"); ++ assert_non_null(p); ++ assert_string_equal(p, "x,a,b,c"); ++ free(p); ++ ++ p = ssh_prefix_without_duplicates("a,b,c", "c,x"); ++ assert_non_null(p); ++ assert_string_equal(p, "c,x,a,b"); ++ free(p); ++} ++ + + int torture_run_tests(void) + { +@@ -275,6 +337,8 @@ int torture_run_tests(void) + cmocka_unit_test(torture_find_all_matching), + cmocka_unit_test(torture_remove_duplicate), + cmocka_unit_test(torture_append_without_duplicate), ++ cmocka_unit_test(torture_remove_all_matching), ++ cmocka_unit_test(torture_prefix_without_duplicates), + }; + + ssh_init(); +-- +2.38.1 + + +From 9c228badc727a95f893b7a9a166a12684eb38d4d Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Mon, 7 Nov 2022 08:23:30 +0100 +Subject: [PATCH 3/6] kex: Add functions for openssh +,-,^ features + +The funcions can: +- add a list to the default list +- remove a list from the default list +- prepend a list to the default list + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + include/libssh/kex.h | 4 ++ + src/kex.c | 105 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 109 insertions(+) + +diff --git a/include/libssh/kex.h b/include/libssh/kex.h +index 3a1f4a6f..23b93924 100644 +--- a/include/libssh/kex.h ++++ b/include/libssh/kex.h +@@ -40,6 +40,10 @@ int ssh_kex_select_methods(ssh_session session); + int ssh_verify_existing_algo(enum ssh_kex_types_e algo, const char *name); + char *ssh_keep_known_algos(enum ssh_kex_types_e algo, const char *list); + char *ssh_keep_fips_algos(enum ssh_kex_types_e algo, const char *list); ++char *ssh_add_to_default_algos(enum ssh_kex_types_e algo, const char *list); ++char *ssh_remove_from_default_algos(enum ssh_kex_types_e algo, ++ const char *list); ++char *ssh_prefix_default_algos(enum ssh_kex_types_e algo, const char *list); + char **ssh_space_tokenize(const char *chain); + int ssh_get_kex1(ssh_session session); + char *ssh_find_matching(const char *in_d, const char *what_d); +diff --git a/src/kex.c b/src/kex.c +index 64083997..1155b9c7 100644 +--- a/src/kex.c ++++ b/src/kex.c +@@ -983,6 +983,111 @@ char *ssh_keep_fips_algos(enum ssh_kex_types_e algo, const char *list) + return ssh_find_all_matching(fips_methods[algo], list); + } + ++/** ++ * @internal ++ * ++ * @brief Return a newly allocated string containing the default ++ * algorithms plus the algorithms specified in list. If the system ++ * runs in fips mode, this will add only fips approved algorithms. ++ * Empty list will cause error. ++ * ++ * @param[in] algo The type of the methods to filter ++ * @param[in] list The list to be appended ++ * ++ * @return A newly allocated list containing the default algorithms and the ++ * algorithms in list at the end; NULL in case of error. ++ */ ++char *ssh_add_to_default_algos(enum ssh_kex_types_e algo, const char *list) ++{ ++ char *tmp = NULL, *ret = NULL; ++ ++ if (algo > SSH_LANG_S_C || list == NULL || list[0] == '\0') { ++ return NULL; ++ } ++ ++ if (ssh_fips_mode()) { ++ tmp = ssh_append_without_duplicates(fips_methods[algo], list); ++ ret = ssh_find_all_matching(fips_methods[algo], tmp); ++ } else { ++ tmp = ssh_append_without_duplicates(default_methods[algo], list); ++ ret = ssh_find_all_matching(supported_methods[algo], tmp); ++ } ++ ++ free(tmp); ++ return ret; ++} ++ ++/** ++ * @internal ++ * ++ * @brief Return a newly allocated string containing the default ++ * algorithms excluding the algorithms specified in list. If the system ++ * runs in fips mode, this will remove from the fips_methods list. ++ * ++ * @param[in] algo The type of the methods to filter ++ * @param[in] list The list to be exclude ++ * ++ * @return A newly allocated list containing the default algorithms without the ++ * algorithms in list; NULL in case of error. ++ */ ++char *ssh_remove_from_default_algos(enum ssh_kex_types_e algo, const char *list) ++{ ++ if (algo > SSH_LANG_S_C) { ++ return NULL; ++ } ++ ++ if (list == NULL || list[0] == '\0') { ++ if (ssh_fips_mode()) { ++ return strdup(fips_methods[algo]); ++ } else { ++ return strdup(default_methods[algo]); ++ } ++ } ++ ++ if (ssh_fips_mode()) { ++ return ssh_remove_all_matching(fips_methods[algo], list); ++ } else { ++ return ssh_remove_all_matching(default_methods[algo], list); ++ } ++} ++ ++/** ++ * @internal ++ * ++ * @brief Return a newly allocated string containing the default ++ * algorithms with prioritized algorithms specified in list. If the ++ * algorithms are present in the default list they get prioritized, if not ++ * they are added to the front of the default list. If the system ++ * runs in fips mode, this will work with the fips_methods list. ++ * Empty list will cause error. ++ * ++ * @param[in] algo The type of the methods to filter ++ * @param[in] list The list to be pushed to priority ++ * ++ * @return A newly allocated list containing the default algorithms prioritized ++ * with the algorithms in list at the beginning of the list; NULL in case ++ * of error. ++ */ ++char *ssh_prefix_default_algos(enum ssh_kex_types_e algo, const char *list) ++{ ++ char *ret = NULL, *tmp = NULL; ++ ++ if (algo > SSH_LANG_S_C || list == NULL || list[0] == '\0') { ++ return NULL; ++ } ++ ++ if (ssh_fips_mode()) { ++ tmp = ssh_prefix_without_duplicates(fips_methods[algo], list); ++ ret = ssh_find_all_matching(fips_methods[algo], tmp); ++ } else { ++ tmp = ssh_prefix_without_duplicates(default_methods[algo], list); ++ ret = ssh_find_all_matching(supported_methods[algo], tmp); ++ } ++ ++ free(tmp); ++ return ret; ++} ++ + int ssh_make_sessionid(ssh_session session) + { + ssh_string num = NULL; +-- +2.38.1 + + +From 0386dd995a70d7cc33292315f670fa08dea6c8b2 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Mon, 7 Nov 2022 13:13:20 +0100 +Subject: [PATCH 4/6] options.c: Add support for openssh config +,-,^ + +These features allow for options Ciphers, HostKeyAlgorithms, KexAlgorithms and +MACs to append, remove and prepend to the default list of algorithms +respectively + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + include/libssh/options.h | 3 +- + src/options.c | 244 +++++++++++++++++++++++++-------------- + src/server.c | 3 +- + 3 files changed, 161 insertions(+), 89 deletions(-) + +diff --git a/include/libssh/options.h b/include/libssh/options.h +index e8dc6c69..dd04c8af 100644 +--- a/include/libssh/options.h ++++ b/include/libssh/options.h +@@ -25,7 +25,8 @@ int ssh_config_parse_file(ssh_session session, const char *filename); + int ssh_config_parse_string(ssh_session session, const char *input); + int ssh_options_set_algo(ssh_session session, + enum ssh_kex_types_e algo, +- const char *list); ++ const char *list, ++ char **place); + int ssh_options_apply(ssh_session session); + + #endif /* _OPTIONS_H */ +diff --git a/src/options.c b/src/options.c +index 49aaefa2..56e09c65 100644 +--- a/src/options.c ++++ b/src/options.c +@@ -221,14 +221,30 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) + + int ssh_options_set_algo(ssh_session session, + enum ssh_kex_types_e algo, +- const char *list) ++ const char *list, ++ char **place) + { +- char *p = NULL; ++ /* When the list start with +,-,^ the filtration of unknown algorithms ++ * gets handled inside the helper functions, otherwise the list is taken ++ * as it is. */ ++ char *p = (char *)list; ++ ++ if (algo < SSH_COMP_C_S) { ++ if (list[0] == '+') { ++ p = ssh_add_to_default_algos(algo, list+1); ++ } else if (list[0] == '-') { ++ p = ssh_remove_from_default_algos(algo, list+1); ++ } else if (list[0] == '^') { ++ p = ssh_prefix_default_algos(algo, list+1); ++ } ++ } + +- if (ssh_fips_mode()) { +- p = ssh_keep_fips_algos(algo, list); +- } else { +- p = ssh_keep_known_algos(algo, list); ++ if (p == list) { ++ if (ssh_fips_mode()) { ++ p = ssh_keep_fips_algos(algo, list); ++ } else { ++ p = ssh_keep_known_algos(algo, list); ++ } + } + + if (p == NULL) { +@@ -238,8 +254,8 @@ int ssh_options_set_algo(ssh_session session, + return -1; + } + +- SAFE_FREE(session->opts.wanted_methods[algo]); +- session->opts.wanted_methods[algo] = p; ++ SAFE_FREE(*place); ++ *place = p; + + return 0; + } +@@ -356,34 +372,60 @@ int ssh_options_set_algo(ssh_session session, + * + * - SSH_OPTIONS_CIPHERS_C_S: + * Set the symmetric cipher client to server (const char *, +- * comma-separated list). ++ * comma-separated list). The list can be prepended by +,-,^ ++ * which can append, remove or move to the beginning ++ * (prioritizing) of the default list respectively. Giving an ++ * empty list after + and ^ will cause error. + * + * - SSH_OPTIONS_CIPHERS_S_C: + * Set the symmetric cipher server to client (const char *, +- * comma-separated list). ++ * comma-separated list). The list can be prepended by +,-,^ ++ * which can append, remove or move to the beginning ++ * (prioritizing) of the default list respectively. Giving an ++ * empty list after + and ^ will cause error. + * + * - SSH_OPTIONS_KEY_EXCHANGE: + * Set the key exchange method to be used (const char *, + * comma-separated list). ex: + * "ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" ++ * The list can be prepended by +,-,^ which will append, ++ * remove or move to the beginning (prioritizing) of the ++ * default list respectively. Giving an empty list ++ * after + and ^ will cause error. + * + * - SSH_OPTIONS_HMAC_C_S: + * Set the Message Authentication Code algorithm client to server +- * (const char *, comma-separated list). ++ * (const char *, comma-separated list). The list can be ++ * prepended by +,-,^ which will append, remove or move to ++ * the beginning (prioritizing) of the default list ++ * respectively. Giving an empty list after + and ^ will ++ * cause error. + * + * - SSH_OPTIONS_HMAC_S_C: + * Set the Message Authentication Code algorithm server to client +- * (const char *, comma-separated list). ++ * (const char *, comma-separated list). The list can be ++ * prepended by +,-,^ which will append, remove or move to ++ * the beginning (prioritizing) of the default list ++ * respectively. Giving an empty list after + and ^ will ++ * cause error. + * + * - SSH_OPTIONS_HOSTKEYS: + * Set the preferred server host key types (const char *, + * comma-separated list). ex: +- * "ssh-rsa,ssh-dss,ecdh-sha2-nistp256" ++ * "ssh-rsa,ssh-dss,ecdh-sha2-nistp256". The list can be ++ * prepended by +,-,^ which will append, remove or move to ++ * the beginning (prioritizing) of the default list ++ * respectively. Giving an empty list after + and ^ will ++ * cause error. + * + * - SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES: + * Set the preferred public key algorithms to be used for + * authentication (const char *, comma-separated list). ex: + * "ssh-rsa,rsa-sha2-256,ssh-dss,ecdh-sha2-nistp256" ++ * The list can be prepended by +,-,^ which will append, ++ * remove or move to the beginning (prioritizing) of the ++ * default list respectively. Giving an empty list ++ * after + and ^ will cause error. + * + * - SSH_OPTIONS_COMPRESSION_C_S: + * Set the compression to use for client to server +@@ -496,6 +538,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + long int i; + unsigned int u; + int rc; ++ char **wanted_methods = session->opts.wanted_methods; + + if (session == NULL) { + return -1; +@@ -779,7 +822,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_invalid(session); + return -1; + } else { +- if (ssh_options_set_algo(session, SSH_CRYPT_C_S, v) < 0) ++ rc = ssh_options_set_algo(session, ++ SSH_CRYPT_C_S, ++ v, ++ &wanted_methods[SSH_CRYPT_C_S]); ++ if (rc < 0) + return -1; + } + break; +@@ -789,7 +836,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_invalid(session); + return -1; + } else { +- if (ssh_options_set_algo(session, SSH_CRYPT_S_C, v) < 0) ++ rc = ssh_options_set_algo(session, ++ SSH_CRYPT_S_C, ++ v, ++ &wanted_methods[SSH_CRYPT_S_C]); ++ if (rc < 0) + return -1; + } + break; +@@ -799,7 +850,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_invalid(session); + return -1; + } else { +- if (ssh_options_set_algo(session, SSH_KEX, v) < 0) ++ rc = ssh_options_set_algo(session, ++ SSH_KEX, ++ v, ++ &wanted_methods[SSH_KEX]); ++ if (rc < 0) + return -1; + } + break; +@@ -809,7 +864,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_invalid(session); + return -1; + } else { +- if (ssh_options_set_algo(session, SSH_HOSTKEYS, v) < 0) ++ rc = ssh_options_set_algo(session, ++ SSH_HOSTKEYS, ++ v, ++ &wanted_methods[SSH_HOSTKEYS]); ++ if (rc < 0) + return -1; + } + break; +@@ -819,20 +878,12 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_invalid(session); + return -1; + } else { +- if (ssh_fips_mode()) { +- p = ssh_keep_fips_algos(SSH_HOSTKEYS, v); +- } else { +- p = ssh_keep_known_algos(SSH_HOSTKEYS, v); +- } +- if (p == NULL) { +- ssh_set_error(session, SSH_REQUEST_DENIED, +- "Setting method: no known public key algorithm (%s)", +- v); ++ rc = ssh_options_set_algo(session, ++ SSH_HOSTKEYS, ++ v, ++ &session->opts.pubkey_accepted_types); ++ if (rc < 0) + return -1; +- } +- +- SAFE_FREE(session->opts.pubkey_accepted_types); +- session->opts.pubkey_accepted_types = p; + } + break; + case SSH_OPTIONS_HMAC_C_S: +@@ -841,7 +892,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_invalid(session); + return -1; + } else { +- if (ssh_options_set_algo(session, SSH_MAC_C_S, v) < 0) ++ rc = ssh_options_set_algo(session, ++ SSH_MAC_C_S, ++ v, ++ &wanted_methods[SSH_MAC_C_S]); ++ if (rc < 0) + return -1; + } + break; +@@ -851,7 +906,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_invalid(session); + return -1; + } else { +- if (ssh_options_set_algo(session, SSH_MAC_S_C, v) < 0) ++ rc = ssh_options_set_algo(session, ++ SSH_MAC_S_C, ++ v, ++ &wanted_methods[SSH_MAC_S_C]); ++ if (rc < 0) + return -1; + } + break; +@@ -861,16 +920,18 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_invalid(session); + return -1; + } else { +- if (strcasecmp(value,"yes")==0){ +- if(ssh_options_set_algo(session,SSH_COMP_C_S,"zlib@openssh.com,zlib,none") < 0) +- return -1; +- } else if (strcasecmp(value,"no")==0){ +- if(ssh_options_set_algo(session,SSH_COMP_C_S,"none,zlib@openssh.com,zlib") < 0) +- return -1; +- } else { +- if (ssh_options_set_algo(session, SSH_COMP_C_S, v) < 0) +- return -1; ++ const char *tmp = v; ++ if (strcasecmp(value, "yes") == 0){ ++ tmp = "zlib@openssh.com,zlib,none"; ++ } else if (strcasecmp(value, "no") == 0){ ++ tmp = "none,zlib@openssh.com,zlib"; + } ++ rc = ssh_options_set_algo(session, ++ SSH_COMP_C_S, ++ tmp, ++ &wanted_methods[SSH_COMP_C_S]); ++ if (rc < 0) ++ return -1; + } + break; + case SSH_OPTIONS_COMPRESSION_S_C: +@@ -879,16 +940,19 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, + ssh_set_error_invalid(session); + return -1; + } else { +- if (strcasecmp(value,"yes")==0){ +- if(ssh_options_set_algo(session,SSH_COMP_S_C,"zlib@openssh.com,zlib,none") < 0) +- return -1; +- } else if (strcasecmp(value,"no")==0){ +- if(ssh_options_set_algo(session,SSH_COMP_S_C,"none,zlib@openssh.com,zlib") < 0) +- return -1; +- } else { +- if (ssh_options_set_algo(session, SSH_COMP_S_C, v) < 0) +- return -1; ++ const char *tmp = v; ++ if (strcasecmp(value, "yes") == 0){ ++ tmp = "zlib@openssh.com,zlib,none"; ++ } else if (strcasecmp(value, "no") == 0){ ++ tmp = "none,zlib@openssh.com,zlib"; + } ++ ++ rc = ssh_options_set_algo(session, ++ SSH_COMP_S_C, ++ tmp, ++ &wanted_methods[SSH_COMP_S_C]); ++ if (rc < 0) ++ return -1; + } + break; + case SSH_OPTIONS_COMPRESSION: +@@ -1604,26 +1668,12 @@ ssh_bind_set_key(ssh_bind sshbind, char **key_loc, const void *value) + + static int ssh_bind_set_algo(ssh_bind sshbind, + enum ssh_kex_types_e algo, +- const char *list) ++ const char *list, ++ char **place) + { +- char *p = NULL; +- +- if (ssh_fips_mode()) { +- p = ssh_keep_fips_algos(algo, list); +- } else { +- p = ssh_keep_known_algos(algo, list); +- } +- if (p == NULL) { +- ssh_set_error(sshbind, SSH_REQUEST_DENIED, +- "Setting method: no algorithm for method \"%s\" (%s)", +- ssh_kex_get_description(algo), list); +- return -1; +- } +- +- SAFE_FREE(sshbind->wanted_methods[algo]); +- sshbind->wanted_methods[algo] = p; +- +- return 0; ++ /* sshbind is needed only for ssh_set_error which takes void* ++ * the typecast is only to satisfy function parameter type */ ++ return ssh_options_set_algo((ssh_session)sshbind, algo, list, place); + } + + /** +@@ -1765,6 +1815,7 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, + char *p, *q; + const char *v; + int i, rc; ++ char **wanted_methods = sshbind->wanted_methods; + + if (sshbind == NULL) { + return -1; +@@ -2014,8 +2065,13 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, + ssh_set_error_invalid(sshbind); + return -1; + } else { +- if (ssh_bind_set_algo(sshbind, SSH_CRYPT_C_S, v) < 0) ++ rc = ssh_bind_set_algo(sshbind, ++ SSH_CRYPT_C_S, ++ v, ++ &wanted_methods[SSH_CRYPT_C_S]); ++ if (rc < 0) { + return -1; ++ } + } + break; + case SSH_BIND_OPTIONS_CIPHERS_S_C: +@@ -2024,8 +2080,13 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, + ssh_set_error_invalid(sshbind); + return -1; + } else { +- if (ssh_bind_set_algo(sshbind, SSH_CRYPT_S_C, v) < 0) ++ rc = ssh_bind_set_algo(sshbind, ++ SSH_CRYPT_S_C, ++ v, ++ &wanted_methods[SSH_CRYPT_S_C]); ++ if (rc < 0) { + return -1; ++ } + } + break; + case SSH_BIND_OPTIONS_KEY_EXCHANGE: +@@ -2034,7 +2095,10 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, + ssh_set_error_invalid(sshbind); + return -1; + } else { +- rc = ssh_bind_set_algo(sshbind, SSH_KEX, v); ++ rc = ssh_bind_set_algo(sshbind, ++ SSH_KEX, ++ v, ++ &wanted_methods[SSH_KEX]); + if (rc < 0) { + return -1; + } +@@ -2046,8 +2110,13 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, + ssh_set_error_invalid(sshbind); + return -1; + } else { +- if (ssh_bind_set_algo(sshbind, SSH_MAC_C_S, v) < 0) ++ rc = ssh_bind_set_algo(sshbind, ++ SSH_MAC_C_S, ++ v, ++ &wanted_methods[SSH_MAC_C_S]); ++ if (rc < 0) { + return -1; ++ } + } + break; + case SSH_BIND_OPTIONS_HMAC_S_C: +@@ -2056,8 +2125,13 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, + ssh_set_error_invalid(sshbind); + return -1; + } else { +- if (ssh_bind_set_algo(sshbind, SSH_MAC_S_C, v) < 0) ++ rc = ssh_bind_set_algo(sshbind, ++ SSH_MAC_S_C, ++ v, ++ &wanted_methods[SSH_MAC_S_C]); ++ if (rc < 0) { + return -1; ++ } + } + break; + case SSH_BIND_OPTIONS_CONFIG_DIR: +@@ -2082,20 +2156,13 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, + ssh_set_error_invalid(sshbind); + return -1; + } else { +- if (ssh_fips_mode()) { +- p = ssh_keep_fips_algos(SSH_HOSTKEYS, v); +- } else { +- p = ssh_keep_known_algos(SSH_HOSTKEYS, v); +- } +- if (p == NULL) { +- ssh_set_error(sshbind, SSH_REQUEST_DENIED, +- "Setting method: no known public key algorithm (%s)", +- v); ++ rc = ssh_bind_set_algo(sshbind, ++ SSH_HOSTKEYS, ++ v, ++ &sshbind->pubkey_accepted_key_types); ++ if (rc < 0) { + return -1; + } +- +- SAFE_FREE(sshbind->pubkey_accepted_key_types); +- sshbind->pubkey_accepted_key_types = p; + } + break; + case SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS: +@@ -2104,7 +2171,10 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, + ssh_set_error_invalid(sshbind); + return -1; + } else { +- rc = ssh_bind_set_algo(sshbind, SSH_HOSTKEYS, v); ++ rc = ssh_bind_set_algo(sshbind, ++ SSH_HOSTKEYS, ++ v, ++ &wanted_methods[SSH_HOSTKEYS]); + if (rc < 0) { + return -1; + } +diff --git a/src/server.c b/src/server.c +index 3fc25bd9..1b423fd0 100644 +--- a/src/server.c ++++ b/src/server.c +@@ -160,7 +160,8 @@ int server_set_kex(ssh_session session) + + rc = ssh_options_set_algo(session, + SSH_HOSTKEYS, +- kept); ++ kept, ++ &session->opts.wanted_methods[SSH_HOSTKEYS]); + SAFE_FREE(kept); + if (rc < 0) { + return -1; +-- +2.38.1 + + +From d96bffca5980496649e03b38eb85bd676ecc1d68 Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Mon, 7 Nov 2022 08:28:31 +0100 +Subject: [PATCH 5/6] torture_options.c: Add test for config +,-,^ feature + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + tests/unittests/torture_options.c | 223 ++++++++++++++++++++++++++++++ + 1 file changed, 223 insertions(+) + +diff --git a/tests/unittests/torture_options.c b/tests/unittests/torture_options.c +index e1d16f02..dc4df383 100644 +--- a/tests/unittests/torture_options.c ++++ b/tests/unittests/torture_options.c +@@ -1087,6 +1087,223 @@ static void torture_options_getopt(void **state) + #endif /* _NSC_VER */ + } + ++static void torture_options_plus_sign(void **state) ++{ ++ ssh_session session = *state; ++ int rc; ++ const char *def_host_alg, *alg, *algs; ++ char *awaited; ++ size_t alg_len, algs_len; ++ ++ if (ssh_fips_mode()) { ++ alg = ",rsa-sha2-512-cert-v01@openssh.com"; ++ algs = ",rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ecdsa-sha2-nistp521"; ++ def_host_alg = ssh_kex_get_fips_methods(SSH_HOSTKEYS); ++ } else { ++ alg = ",ssh-rsa"; ++ algs = ",ssh-rsa,ssh-rsa-cert-v01@openssh.com"; ++ def_host_alg = ssh_kex_get_default_methods(SSH_HOSTKEYS); ++ } ++ alg_len = strlen(alg); ++ algs_len = strlen(algs); ++ ++ /* in fips mode, the default list is the available list, which means ++ * we can't append anything because everything enabled is already ++ * included */ ++ if (ssh_fips_mode()) { ++ awaited = strdup(def_host_alg); ++ assert_non_null(awaited); ++ } else { ++ awaited = calloc(strlen(def_host_alg) + alg_len + 1, 1); ++ assert_non_null(awaited); ++ ++ memcpy(awaited, def_host_alg, strlen(def_host_alg)); ++ memcpy(awaited+strlen(def_host_alg), alg, alg_len); ++ } ++ ++ if (ssh_fips_mode()) { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "+rsa-sha2-512-cert-v01@openssh.com"); ++ } else { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "+ssh-rsa"); ++ } ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ awaited); ++ ++ if (!ssh_fips_mode()) { ++ /* different algorithm list is used here */ ++ free(awaited); ++ ++ awaited = calloc(strlen(def_host_alg) + algs_len + 1, 1); ++ assert_non_null(awaited); ++ memcpy(awaited, def_host_alg, strlen(def_host_alg)); ++ memcpy(awaited+strlen(def_host_alg), algs, algs_len); ++ } ++ ++ if (ssh_fips_mode()) { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, ++ "+rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ecdsa-sha2-nistp521"); ++ } else { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, ++ "+ssh-rsa,ssh-rsa-cert-v01@openssh.com"); ++ } ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ awaited); ++ ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "+"); ++ assert_ssh_return_code_equal(session, rc, SSH_ERROR); ++ ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "+blablabla"); ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ def_host_alg); ++ ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, NULL); ++ assert_ssh_return_code_equal(session, rc, SSH_ERROR); ++ ++ free(awaited); ++} ++ ++static void torture_options_minus_sign(void **state) ++{ ++ ssh_session session = *state; ++ int rc; ++ const char *def_host_alg, *alg, *algs; ++ char *awaited, *p; ++ size_t alg_len, algs_len; ++ ++ if (ssh_fips_mode()) { ++ alg = "rsa-sha2-512-cert-v01@openssh.com,"; ++ algs = "rsa-sha2-256-cert-v01@openssh.com,ecdsa-sha2-nistp521,"; ++ def_host_alg = ssh_kex_get_fips_methods(SSH_HOSTKEYS); ++ } else { ++ alg = "ssh-ed25519,"; ++ algs = "ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,"; ++ def_host_alg = ssh_kex_get_default_methods(SSH_HOSTKEYS); ++ } ++ alg_len = strlen(alg); ++ algs_len = strlen(algs); ++ ++ awaited = calloc(strlen(def_host_alg) + 1, 1); ++ assert_non_null(awaited); ++ ++ memcpy(awaited, def_host_alg, strlen(def_host_alg)); ++ p = strstr(awaited, alg); ++ assert_non_null(p); ++ memmove(p, p+alg_len, strlen(p + alg_len) + 1); ++ ++ if (ssh_fips_mode()) { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "-rsa-sha2-512-cert-v01@openssh.com"); ++ } else { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "-ssh-ed25519"); ++ } ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ awaited); ++ ++ p = strstr(awaited, algs); ++ assert_non_null(p); ++ memmove(p, p+algs_len, strlen(p + algs_len) + 1); ++ ++ if (ssh_fips_mode()) { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ecdsa-sha2-nistp521"); ++ } else { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "-ssh-ed25519,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384"); ++ } ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ awaited); ++ ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "-"); ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ def_host_alg); ++ ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "-blablabla"); ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ def_host_alg); ++ ++ free(awaited); ++} ++ ++static void torture_options_caret_sign(void **state) ++{ ++ ssh_session session = *state; ++ int rc; ++ const char *def_host_alg, *alg, *algs; ++ size_t alg_len, algs_len; ++ char *awaited, *p; ++ ++ if (ssh_fips_mode()) { ++ alg = "rsa-sha2-512-cert-v01@openssh.com,"; ++ algs = "rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ecdsa-sha2-nistp521,"; ++ def_host_alg = ssh_kex_get_fips_methods(SSH_HOSTKEYS); ++ } else { ++ alg = "ssh-rsa,"; ++ algs = "ssh-rsa,ssh-rsa-cert-v01@openssh.com,"; ++ def_host_alg = ssh_kex_get_default_methods(SSH_HOSTKEYS); ++ } ++ alg_len = strlen(alg); ++ algs_len = strlen(algs); ++ ++ awaited = calloc(strlen(def_host_alg) + alg_len + 1, 1); ++ assert_non_null(awaited); ++ ++ memcpy(awaited, alg, alg_len); ++ memcpy(awaited+alg_len, def_host_alg, strlen(def_host_alg)); ++ if (ssh_fips_mode()) { ++ p = strstr(awaited, alg); ++ /* look for second occurrence */ ++ p = strstr(p+1, algs); ++ memmove(p, p+alg_len, strlen(p + alg_len) + 1); ++ } ++ ++ if (ssh_fips_mode()) { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "^rsa-sha2-512-cert-v01@openssh.com"); ++ } else { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "^ssh-rsa"); ++ } ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ awaited); ++ /* different algorithm list is used here */ ++ free(awaited); ++ ++ awaited = calloc(strlen(def_host_alg) + algs_len + 1, 1); ++ assert_non_null(awaited); ++ memcpy(awaited, algs, algs_len); ++ memcpy(awaited+algs_len, def_host_alg, strlen(def_host_alg)); ++ if (ssh_fips_mode()) { ++ p = strstr(awaited, algs); ++ /* look for second occurrence */ ++ p = strstr(p+1, algs); ++ memmove(p, p+algs_len, strlen(p + algs_len) + 1); ++ } ++ ++ if (ssh_fips_mode()) { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, ++ "^rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ecdsa-sha2-nistp521"); ++ } else { ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, ++ "^ssh-rsa,ssh-rsa-cert-v01@openssh.com"); ++ } ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ awaited); ++ ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "^"); ++ assert_ssh_return_code_equal(session, rc, SSH_ERROR); ++ ++ rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "^blablabla"); ++ assert_ssh_return_code(session, rc); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], ++ def_host_alg); ++ ++ free(awaited); ++} ++ + #ifdef WITH_SERVER + const char template[] = "temp_dir_XXXXXX"; + +@@ -1881,6 +2098,12 @@ int torture_run_tests(void) { + setup, teardown), + cmocka_unit_test_setup_teardown(torture_options_getopt, + setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_options_plus_sign, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_options_minus_sign, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_options_caret_sign, ++ setup, teardown), + }; + + #ifdef WITH_SERVER +-- +2.38.1 + + +From 535425e6ebebae5e3a1f1117ae1fd687633df1ae Mon Sep 17 00:00:00 2001 +From: Norbert Pocs +Date: Thu, 10 Nov 2022 10:50:52 +0100 +Subject: [PATCH 6/6] torture_config.c: Add test for +,-,^ config feature + +It should be possible to use features to add,remove,prioritize +algorithms in the algorithm list from the config file. + +Signed-off-by: Norbert Pocs +Reviewed-by: Jakub Jelen +--- + tests/unittests/torture_config.c | 393 +++++++++++++++++++++++++++++++ + 1 file changed, 393 insertions(+) + +diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c +index 31dadae3..354adc2f 100644 +--- a/tests/unittests/torture_config.c ++++ b/tests/unittests/torture_config.c +@@ -40,6 +40,9 @@ extern LIBSSH_THREAD int ssh_log_level; + #define LIBSSH_TESTCONFIG10 "libssh_testconfig10.tmp" + #define LIBSSH_TESTCONFIG11 "libssh_testconfig11.tmp" + #define LIBSSH_TESTCONFIG12 "libssh_testconfig12.tmp" ++#define LIBSSH_TESTCONFIG14 "libssh_testconfig14.tmp" ++#define LIBSSH_TESTCONFIG15 "libssh_testconfig15.tmp" ++#define LIBSSH_TESTCONFIG16 "libssh_testconfig16.tmp" + #define LIBSSH_TESTCONFIGGLOB "libssh_testc*[36].tmp" + #define LIBSSH_TEST_PUBKEYTYPES "libssh_test_PubkeyAcceptedKeyTypes.tmp" + #define LIBSSH_TEST_PUBKEYALGORITHMS "libssh_test_PubkeyAcceptedAlgorithms.tmp" +@@ -181,6 +184,27 @@ extern LIBSSH_THREAD int ssh_log_level; + "IdentityFile id_rsa_one\n" \ + "IdentityFile id_ecdsa_two\n" + ++/* +,-,^ features for all supported list */ ++/* kex won't work in fips */ ++#define LIBSSH_TESTCONFIG_STRING14 \ ++ "HostKeyAlgorithms +ssh-rsa\n" \ ++ "Ciphers +aes128-cbc,aes256-cbc\n" \ ++ "KexAlgorithms +diffie-hellman-group14-sha1,diffie-hellman-group1-sha1\n" \ ++ "MACs +hmac-sha1,hmac-sha1-etm@openssh.com\n" ++ ++/* have to be algorithms which are in the default list */ ++#define LIBSSH_TESTCONFIG_STRING15 \ ++ "HostKeyAlgorithms -rsa-sha2-512,rsa-sha2-256\n" \ ++ "Ciphers -aes256-ctr\n" \ ++ "KexAlgorithms -diffie-hellman-group18-sha512,diffie-hellman-group16-sha512\n" \ ++ "MACs -hmac-sha2-256-etm@openssh.com\n" ++ ++#define LIBSSH_TESTCONFIG_STRING16 \ ++ "HostKeyAlgorithms ^rsa-sha2-512,rsa-sha2-256\n" \ ++ "Ciphers ^aes256-cbc\n" \ ++ "KexAlgorithms ^diffie-hellman-group18-sha512,diffie-hellman-group16-sha512\n" \ ++ "MACs ^hmac-sha1\n" ++ + #define LIBSSH_TEST_PUBKEYTYPES_STRING \ + "PubkeyAcceptedKeyTypes "PUBKEYACCEPTEDTYPES"\n" + +@@ -238,6 +262,9 @@ static int setup_config_files(void **state) + unlink(LIBSSH_TESTCONFIG10); + unlink(LIBSSH_TESTCONFIG11); + unlink(LIBSSH_TESTCONFIG12); ++ unlink(LIBSSH_TESTCONFIG14); ++ unlink(LIBSSH_TESTCONFIG15); ++ unlink(LIBSSH_TESTCONFIG16); + unlink(LIBSSH_TEST_PUBKEYTYPES); + unlink(LIBSSH_TEST_PUBKEYALGORITHMS); + unlink(LIBSSH_TEST_NONEWLINEEND); +@@ -285,6 +312,14 @@ static int setup_config_files(void **state) + torture_write_file(LIBSSH_TESTCONFIG12, + LIBSSH_TESTCONFIG_STRING12); + ++ /* +,-,^ feature */ ++ torture_write_file(LIBSSH_TESTCONFIG14, ++ LIBSSH_TESTCONFIG_STRING14); ++ torture_write_file(LIBSSH_TESTCONFIG15, ++ LIBSSH_TESTCONFIG_STRING15); ++ torture_write_file(LIBSSH_TESTCONFIG16, ++ LIBSSH_TESTCONFIG_STRING16); ++ + torture_write_file(LIBSSH_TEST_PUBKEYTYPES, + LIBSSH_TEST_PUBKEYTYPES_STRING); + +@@ -316,6 +351,9 @@ static int teardown_config_files(void **state) + unlink(LIBSSH_TESTCONFIG10); + unlink(LIBSSH_TESTCONFIG11); + unlink(LIBSSH_TESTCONFIG12); ++ unlink(LIBSSH_TESTCONFIG14); ++ unlink(LIBSSH_TESTCONFIG15); ++ unlink(LIBSSH_TESTCONFIG16); + unlink(LIBSSH_TEST_PUBKEYTYPES); + unlink(LIBSSH_TEST_PUBKEYALGORITHMS); + +@@ -1267,6 +1305,349 @@ static void torture_config_rekey_string(void **state) + torture_config_rekey(state, NULL, LIBSSH_TESTCONFIG_STRING12); + } + ++/** ++ * @brief Remove substring from a string ++ * ++ * @param occurrence 0 means "remove the first occurrence" ++ * 1 means "remove the second occurrence" and so on ++ */ ++static void helper_remove_substring(char *s, const char *subs, int occurrence) { ++ char *p; ++ /* remove the substring from the defaults */ ++ p = strstr(s, subs); ++ assert_non_null(p); ++ /* look for second occurrence */ ++ for (int i = 0; i < occurrence; i++) { ++ p = strstr(p + 1, subs); ++ assert_non_null(p); ++ } ++ memmove(p, p + strlen(subs), strlen(p + strlen(subs)) + 1); ++} ++ ++/** ++ * @brief test that openssh style '+' feature works ++ */ ++static void torture_config_plus(void **state, ++ const char *file, const char *string) ++{ ++ ssh_session session = *state; ++ const char *def_hostkeys = ssh_kex_get_default_methods(SSH_HOSTKEYS); ++ const char *fips_hostkeys = ssh_kex_get_fips_methods(SSH_HOSTKEYS); ++ const char *def_ciphers = ssh_kex_get_default_methods(SSH_CRYPT_C_S); ++ const char *fips_ciphers = ssh_kex_get_fips_methods(SSH_CRYPT_C_S); ++ const char *def_kex = ssh_kex_get_default_methods(SSH_KEX); ++ const char *fips_kex = ssh_kex_get_fips_methods(SSH_KEX); ++ const char *def_mac = ssh_kex_get_default_methods(SSH_MAC_C_S); ++ const char *fips_mac = ssh_kex_get_fips_methods(SSH_MAC_C_S); ++ const char *hostkeys_added = ",ssh-rsa"; ++ const char *ciphers_added = "aes128-cbc,aes256-cbc"; ++ const char *kex_added = ",diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"; ++ const char *mac_added = ",hmac-sha1,hmac-sha1-etm@openssh.com"; ++ char *awaited = NULL; ++ int rc; ++ ++ _parse_config(session, file, string, SSH_OK); ++ ++ /* check hostkeys */ ++ if (ssh_fips_mode()) { ++ /* ssh-rsa is disabled in fips */ ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], fips_hostkeys); ++ } else { ++ awaited = calloc(strlen(def_hostkeys) + strlen(hostkeys_added) + 1, 1); ++ rc = snprintf(awaited, strlen(def_hostkeys) + strlen(hostkeys_added) + 1, ++ "%s%s", def_hostkeys, hostkeys_added); ++ assert_int_equal(rc, strlen(def_hostkeys) + strlen(hostkeys_added)); ++ ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], awaited); ++ free(awaited); ++ } ++ ++ /* check ciphers */ ++ if (ssh_fips_mode()) { ++ /* already all supported is in the list */ ++ assert_string_equal(session->opts.wanted_methods[SSH_CRYPT_C_S], fips_ciphers); ++ } else { ++ awaited = calloc(strlen(def_ciphers) + strlen(ciphers_added) + 1, 1); ++ rc = snprintf(awaited, strlen(def_ciphers) + strlen(ciphers_added) + 1, ++ "%s%s", def_ciphers, ciphers_added); ++ assert_int_equal(rc, strlen(def_ciphers) + strlen(ciphers_added)); ++ assert_string_equal(session->opts.wanted_methods[SSH_CRYPT_C_S], awaited); ++ free(awaited); ++ } ++ ++ /* check kex */ ++ if (ssh_fips_mode()) { ++ /* sha1 is disabled in fips */ ++ assert_string_equal(session->opts.wanted_methods[SSH_KEX], fips_kex); ++ } else { ++ awaited = calloc(strlen(def_kex) + strlen(kex_added) + 1, 1); ++ rc = snprintf(awaited, strlen(def_kex) + strlen(kex_added) + 1, ++ "%s%s", def_kex, kex_added); ++ assert_int_equal(rc, strlen(def_kex) + strlen(kex_added)); ++ assert_string_equal(session->opts.wanted_methods[SSH_KEX], awaited); ++ free(awaited); ++ } ++ ++ /* check mac */ ++ if (ssh_fips_mode()) { ++ /* the added algos are already in the fips_methods */ ++ assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S], fips_mac); ++ } else { ++ awaited = calloc(strlen(def_mac) + strlen(mac_added) + 1, 1); ++ rc = snprintf(awaited, strlen(def_mac) + strlen(mac_added) + 1, ++ "%s%s", def_mac, mac_added); ++ assert_int_equal(rc, strlen(def_mac) + strlen(mac_added)); ++ assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S], awaited); ++ free(awaited); ++ } ++} ++ ++/** ++ * @brief test that openssh style '+' feature works from file ++ */ ++static void torture_config_plus_file(void **state) ++{ ++ torture_config_plus(state, LIBSSH_TESTCONFIG14, NULL); ++} ++ ++/** ++ * @brief test that openssh style '+' feature works from string ++ */ ++static void torture_config_plus_string(void **state) ++{ ++ torture_config_plus(state, NULL, LIBSSH_TESTCONFIG_STRING14); ++} ++ ++/** ++ * @brief test that openssh style '-' feature works from string ++ */ ++static void torture_config_minus(void **state, ++ const char *file, const char *string) ++{ ++ ssh_session session = *state; ++ const char *def_hostkeys = ssh_kex_get_default_methods(SSH_HOSTKEYS); ++ const char *fips_hostkeys = ssh_kex_get_fips_methods(SSH_HOSTKEYS); ++ const char *def_ciphers = ssh_kex_get_default_methods(SSH_CRYPT_C_S); ++ const char *fips_ciphers = ssh_kex_get_fips_methods(SSH_CRYPT_C_S); ++ const char *def_kex = ssh_kex_get_default_methods(SSH_KEX); ++ const char *fips_kex = ssh_kex_get_fips_methods(SSH_KEX); ++ const char *def_mac = ssh_kex_get_default_methods(SSH_MAC_C_S); ++ const char *fips_mac = ssh_kex_get_fips_methods(SSH_MAC_C_S); ++ const char *hostkeys_removed = ",rsa-sha2-512,rsa-sha2-256"; ++ const char *ciphers_removed = ",aes256-ctr"; ++ const char *kex_removed = ",diffie-hellman-group18-sha512,diffie-hellman-group16-sha512"; ++ const char *fips_kex_removed = ",diffie-hellman-group16-sha512,diffie-hellman-group18-sha512"; ++ const char *mac_removed = "hmac-sha2-256-etm@openssh.com,"; ++ char *awaited = NULL; ++ int rc; ++ ++ _parse_config(session, file, string, SSH_OK); ++ ++ /* check hostkeys */ ++ if (ssh_fips_mode()) { ++ awaited = calloc(strlen(fips_hostkeys) + 1, 1); ++ rc = snprintf(awaited, strlen(fips_hostkeys) + 1, "%s", fips_hostkeys); ++ assert_int_equal(rc, strlen(fips_hostkeys)); ++ } else { ++ awaited = calloc(strlen(def_hostkeys) + 1, 1); ++ rc = snprintf(awaited, strlen(def_hostkeys) + 1, "%s", def_hostkeys); ++ assert_int_equal(rc, strlen(def_hostkeys)); ++ } ++ /* remove the substring from the defaults */ ++ helper_remove_substring(awaited, hostkeys_removed, 0); ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], awaited); ++ free(awaited); ++ ++ /* check ciphers */ ++ if (ssh_fips_mode()) { ++ awaited = calloc(strlen(fips_ciphers) + 1, 1); ++ rc = snprintf(awaited, strlen(fips_ciphers) + 1, "%s", fips_ciphers); ++ assert_int_equal(rc, strlen(fips_ciphers)); ++ } else { ++ awaited = calloc(strlen(def_ciphers) + 1, 1); ++ rc = snprintf(awaited, strlen(def_ciphers) + 1, "%s", def_ciphers); ++ assert_int_equal(rc, strlen(def_ciphers)); ++ /* remove the comma at the end of the list */ ++ awaited[strlen(awaited) - 1] = '\0'; ++ } ++ /* remove the substring from the defaults */ ++ helper_remove_substring(awaited, ciphers_removed, 0); ++ assert_string_equal(session->opts.wanted_methods[SSH_CRYPT_C_S], awaited); ++ free(awaited); ++ ++ /* check kex */ ++ if (ssh_fips_mode()) { ++ awaited = calloc(strlen(fips_kex) + 1, 1); ++ rc = snprintf(awaited, strlen(fips_kex) + 1, "%s", fips_kex); ++ assert_int_equal(rc, strlen(fips_kex)); ++ /* remove the substring from the defaults */ ++ helper_remove_substring(awaited, fips_kex_removed, 0); ++ } else { ++ awaited = calloc(strlen(def_kex) + 1, 1); ++ rc = snprintf(awaited, strlen(def_kex) + 1, "%s", def_kex); ++ assert_int_equal(rc, strlen(def_kex)); ++ /* remove the substring from the defaults */ ++ helper_remove_substring(awaited, kex_removed, 0); ++ } ++ assert_string_equal(session->opts.wanted_methods[SSH_KEX], awaited); ++ free(awaited); ++ ++ /* check mac */ ++ if (ssh_fips_mode()) { ++ awaited = calloc(strlen(fips_mac) + 1, 1); ++ rc = snprintf(awaited, strlen(fips_mac) + 1, "%s", fips_mac); ++ assert_int_equal(rc, strlen(fips_mac)); ++ } else { ++ awaited = calloc(strlen(def_mac) + 1, 1); ++ rc = snprintf(awaited, strlen(def_mac) + 1, "%s", def_mac); ++ assert_int_equal(rc, strlen(def_mac)); ++ } ++ /* remove the substring from the defaults */ ++ helper_remove_substring(awaited, mac_removed, 0); ++ assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S], awaited); ++ free(awaited); ++} ++ ++/** ++ * @brief test that openssh style '-' feature works from file ++ */ ++static void torture_config_minus_file(void **state) ++{ ++ torture_config_minus(state, LIBSSH_TESTCONFIG15, NULL); ++} ++ ++/** ++ * @brief test that openssh style '-' feature works from string ++ */ ++static void torture_config_minus_string(void **state) ++{ ++ torture_config_minus(state, NULL, LIBSSH_TESTCONFIG_STRING15); ++} ++ ++/** ++ * @brief test that openssh style '^' feature works from string ++ */ ++static void torture_config_caret(void **state, ++ const char *file, const char *string) ++{ ++ ssh_session session = *state; ++ const char *def_hostkeys = ssh_kex_get_default_methods(SSH_HOSTKEYS); ++ const char *fips_hostkeys = ssh_kex_get_fips_methods(SSH_HOSTKEYS); ++ const char *def_ciphers = ssh_kex_get_default_methods(SSH_CRYPT_C_S); ++ const char *fips_ciphers = ssh_kex_get_fips_methods(SSH_CRYPT_C_S); ++ const char *def_kex = ssh_kex_get_default_methods(SSH_KEX); ++ const char *fips_kex = ssh_kex_get_fips_methods(SSH_KEX); ++ const char *def_mac = ssh_kex_get_default_methods(SSH_MAC_C_S); ++ const char *fips_mac = ssh_kex_get_fips_methods(SSH_MAC_C_S); ++ const char *hostkeys_prio = "rsa-sha2-512,rsa-sha2-256"; ++ const char *ciphers_prio = "aes256-cbc,"; ++ const char *kex_prio = "diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,"; ++ const char *fips_kex_prio = ",diffie-hellman-group16-sha512,diffie-hellman-group18-sha512"; ++ const char *mac_prio = "hmac-sha1,"; ++ char *awaited = NULL; ++ int rc; ++ ++ _parse_config(session, file, string, SSH_OK); ++ ++ /* check hostkeys */ ++ /* +2 for the added comma and the \0 */ ++ if (ssh_fips_mode()) { ++ awaited = calloc(strlen(hostkeys_prio) + strlen(fips_hostkeys) + 2, 1); ++ rc = snprintf(awaited, strlen(hostkeys_prio) + strlen(fips_hostkeys) + 2, ++ "%s,%s", hostkeys_prio, fips_hostkeys); ++ assert_int_equal(rc, strlen(hostkeys_prio) + strlen(fips_hostkeys) + 1); ++ } else { ++ awaited = calloc(strlen(def_hostkeys) + strlen(hostkeys_prio) + 2, 1); ++ rc = snprintf(awaited, strlen(hostkeys_prio) + strlen(def_hostkeys) + 2, ++ "%s,%s", hostkeys_prio, def_hostkeys); ++ assert_int_equal(rc, strlen(hostkeys_prio) + strlen(def_hostkeys) + 1); ++ } ++ ++ /* remove the substring from the defaults */ ++ helper_remove_substring(awaited, hostkeys_prio, 1); ++ /* remove the comma at the end of the list */ ++ awaited[strlen(awaited) - 1] = '\0'; ++ ++ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], awaited); ++ free(awaited); ++ ++ /* check ciphers */ ++ if (ssh_fips_mode()) { ++ awaited = calloc(strlen(ciphers_prio) + strlen(fips_ciphers) + 1, 1); ++ rc = snprintf(awaited, strlen(ciphers_prio) + strlen(fips_ciphers) + 1, ++ "%s%s", ciphers_prio, fips_ciphers); ++ assert_int_equal(rc, strlen(ciphers_prio) + strlen(fips_ciphers)); ++ /* remove the substring from the defaults */ ++ helper_remove_substring(awaited, ciphers_prio, 1); ++ } else { ++ /* + 2 because the '\0' and the comma */ ++ awaited = calloc(strlen(ciphers_prio) + strlen(def_ciphers) + 1, 1); ++ rc = snprintf(awaited, strlen(ciphers_prio) + strlen(def_ciphers) + 1, ++ "%s%s", ciphers_prio, def_ciphers); ++ assert_int_equal(rc, strlen(ciphers_prio) + strlen(def_ciphers)); ++ /* remove the comma at the end of the list */ ++ awaited[strlen(awaited) - 1] = '\0'; ++ } ++ ++ assert_string_equal(session->opts.wanted_methods[SSH_CRYPT_C_S], awaited); ++ free(awaited); ++ ++ /* check kex */ ++ if (ssh_fips_mode()) { ++ awaited = calloc(strlen(kex_prio) + strlen(fips_kex) + 1, 1); ++ rc = snprintf(awaited, strlen(kex_prio) + strlen(fips_kex) + 1, ++ "%s%s", kex_prio, fips_kex); ++ assert_int_equal(rc, strlen(kex_prio) + strlen(fips_kex)); ++ /* remove the substring from the defaults */ ++ /* the default list has different order of these two algos than the fips ++ * and because here is a braindead string substitution being done, ++ * change the order and remove the first occurrence of it */ ++ helper_remove_substring(awaited, fips_kex_prio, 0); ++ } else { ++ awaited = calloc(strlen(kex_prio) + strlen(def_kex) + 1, 1); ++ rc = snprintf(awaited, strlen(kex_prio) + strlen(def_kex) + 1, ++ "%s%s", kex_prio, def_kex); ++ assert_int_equal(rc, strlen(def_kex) + strlen(kex_prio)); ++ /* remove the substring from the defaults */ ++ helper_remove_substring(awaited, kex_prio, 1); ++ } ++ ++ assert_string_equal(session->opts.wanted_methods[SSH_KEX], awaited); ++ free(awaited); ++ ++ /* check mac */ ++ if (ssh_fips_mode()) { ++ awaited = calloc(strlen(mac_prio) + strlen(fips_mac) + 1, 1); ++ rc = snprintf(awaited, strlen(mac_prio) + strlen(fips_mac) + 1, "%s%s", mac_prio, fips_mac); ++ assert_int_equal(rc, strlen(mac_prio) + strlen(fips_mac)); ++ /* the fips list contains hmac-sha1 algo */ ++ helper_remove_substring(awaited, mac_prio, 1); ++ } else { ++ awaited = calloc(strlen(mac_prio) + strlen(def_mac) + 1, 1); ++ /* the mac is not in default; it is added to the list */ ++ rc = snprintf(awaited, strlen(mac_prio) + strlen(def_mac) + 1, "%s%s", mac_prio, def_mac); ++ assert_int_equal(rc, strlen(mac_prio) + strlen(def_mac)); ++ } ++ assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S], awaited); ++ free(awaited); ++} ++ ++/** ++ * @brief test that openssh style '^' feature works from file ++ */ ++static void torture_config_caret_file(void **state) ++{ ++ torture_config_caret(state, LIBSSH_TESTCONFIG16, NULL); ++} ++ ++/** ++ * @brief test that openssh style '^' feature works from string ++ */ ++static void torture_config_caret_string(void **state) ++{ ++ torture_config_caret(state, NULL, LIBSSH_TESTCONFIG_STRING16); ++} ++ + /** + * @brief test PubkeyAcceptedKeyTypes helper function + */ +@@ -1848,6 +2229,18 @@ int torture_run_tests(void) + setup, teardown), + cmocka_unit_test_setup_teardown(torture_config_rekey_string, + setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_config_plus_file, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_config_plus_string, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_config_minus_file, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_config_minus_string, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_config_caret_file, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(torture_config_caret_string, ++ setup, teardown), + cmocka_unit_test_setup_teardown(torture_config_pubkeytypes_file, + setup, teardown), + cmocka_unit_test_setup_teardown(torture_config_pubkeytypes_string, +-- +2.38.1 +